JAVA之旅(八)——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例
JAVA之旅(八)——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例
学习是不能停止的
一.多态
我们今天又要学习一个新的概念了,就是多态,它是面向对象的第三个特征,何谓多态?
- 定义
某一类事物的多种存在方式
- 比如
动物中的猫狗,人类中的男人,女人
我们可以把多态理解为事物存在的多种体现形态
当我们new一个猫类的时候,和new 一个动物,其实是一样的,多种形态变现
所以我们可以分这几部分分析
- 多态的体现
- 多态的前提
- 3.多态的好处
- 4.多态的应用
我们定义一个需求,描述动物,正常的逻辑应该是这样描述的
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 动物: 猫,狗
*/
Cat c = new Cat();
c.eat();
dog d = new dog();
d.eat();
}
}
/**
* 动物
*
* @author LGL
*
*/
abstract class Animal {
// 吃什么不确定,抽象
abstract void eat();
}
/**
* 猫
*
* @author LGL
*
*/
class Cat extends Animal {
@Override
void eat() {
System.out.println("猫吃鱼");
}
}
/**
* 狗类
*
* @author LGL
*
*/
class dog extends Animal {
@Override
void eat() {
System.out.println("狗吃骨头");
}
}
这个体系我们展现出来一个为题,我们为了使用猫吃东西和狗吃东西,得new两个对象,要是多来几只小动物,我不还得new死,所以我们要想一个解决办法,他们有一个共性,就是都是动物,我们可以这样转换
Animal a = new Cat();
a.eat();
因为也是动物类型,我们输出
这就是多态在程序中的表现
- 父类的引用指向了自己的子类对象,这就是多态的代码体现形式,人 = new 男人,换句话说,父类的引用也可以接收子类的对象,所以我们可以这样定义一个方法
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 动物: 猫,狗
*/
AnimalEat(new Cat());
AnimalEat(new dog());
}
public static void AnimalEat(Animal a) {
a.eat();
}
}
这样就方便了,这样也就体现了多态的好处:
- 多态的出现大大的提升了程序的扩展性
但是有前提的
- 必须类与类之间有关系,要么继承,要么实现
- 通常,还有一个前提就是存在覆盖
不过,有利有弊,还是会存在弊端的
- 提高了扩展性,但是只能使用父类的引用访问父类的成员,这是局限性,但是我们侧重扩展性
我们再返回前面说多态的转型,我们看这段代码
//类型提升
Animal a = new Cat();
a.eat();
我们也叫作向上转型,
如果想要调属性,该如何操作(向下转型)?
- 强制将父类的引用转为子类类型
Animal a = new Cat();
a.eat();
Cat c = (Cat)a;
c.sleep();
也就是说,转型是强制将父类的引用,转为子类类型,向下转型。千万不要将父类对象转成子类对象,我们能转换的是父类引用指向子类对象的子类,多态自始至终都是子类对象在做着变化
那么你会了强转之后,你就说,我可以这样做
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 动物: 猫,狗
*/
AnimalEat(new Cat());
AnimalEat(new dog());
}
public static void AnimalEat(Animal a) {
a.eat();
Cat c = (Cat) a;
c.sleep();
}
}
这样是不是可以?我们看结果
这里报错了,提示的是狗类型不行转换成猫类型,的确,不能随便乱转。我们价格判断,怎么判断呢?条件语句该怎么写呢?这里我们又有一个关键字了instanceof
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 动物: 猫,狗
*/
AnimalEat(new Cat());
AnimalEat(new dog());
}
public static void AnimalEat(Animal a) {
a.eat();
//如果a的类型是Cat就执行
if(a instanceof Cat){
Cat c = (Cat) a;
c.sleep();
}
}
}
这样我们加了判断之后,我们就可以知道
既然多态说了这么多,我们来看看多态的应用吧,还是以一个需求开始去分析
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 需求:幼儿园有两个班 大班: 学习,睡觉 小班: 学习,睡觉 可以将两类事物进行抽取
*/
SmallClass s = new SmallClass();
s.study();
s.sleep();
BigClass b = new BigClass();
b.study();
}
}
/**
* 学生类
*
* @author LGL
*
*/
abstract class Student {
// 学习的内容不一样,抽象
public abstract void study();
// 睡觉
public void sleep() {
System.out.println("躺着睡");
}
}
/**
* 大班
*
* @author LGL
*
*/
class BigClass extends Student {
@Override
public void study() {
System.out.println("学习大班知识");
}
}
/**
* 小班
*
* @author LGL
*
*/
class SmallClass extends Student {
@Override
public void study() {
System.out.println("学习小班知识");
}
@Override
public void sleep() {
System.out.println("卧着睡");
}
}
这个例子输出
你拿到一想,是不是根据上面的方法直接复用父类对象的引用?这里我们可以拿到一个单独的类去复用封装
/**
* 封装工具类
*
* @author LGL
*
*/
class DoStudent {
public void dosome(Student s) {
s.study();
s.sleep();
}
}
这样我们使用
DoStudent dos = new DoStudent();
dos.dosome(new BigClass());
dos.dosome(new SmallClass());
得到的结果
我们再来看下多态的代码特点,我们举个例子
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
zi z = new zi();
z.method1();
z.method2();
z.method3();
}
}
class Fu {
void method1() {
System.out.println("fu method1");
}
void method2() {
System.out.println("fu method2");
}
}
class zi extends Fu {
void method1() {
System.out.println("zi method1");
}
void method3() {
System.out.println("zi method3");
}
}
你能告诉我打印的结果吗?
我们现在用多态的思想去做
你会知道,3是引用不了的,我现在把报错的的地方注释掉,然后你能告诉我运行的结果吗
我们可以总结出特点(在多态中成员函数的特点)
- 在编译时期。参阅引用型变量所属的类是否有调用的方法,如果由,编译通过。如果没有编译失败
- 在运行时期,参阅对象所属的类中是否有调用的方法
- 简单总结就是成员函数在多态调用时,编译看左边,运行看右边
我们再在子类和父类中都定义一个int值分别是5和8
我们这么输出
Fu f = new zi();
System.out.println(f.num);
zi z = new zi();
System.out.println(z.num);
输出多少呢?
这里就总结出
- 在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属)
- 在多态中,静态成员变量的特点:无论编译和运行,都参考左边
我们把学到的应用在案例上
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 需求:电脑运行实例,电脑运行基于主板
*/
MainBoard b = new MainBoard();
b.run();
}
}
/**
* 主板
*
* @author LGL
*
*/
class MainBoard {
public void run() {
System.out.println("主板运行了");
}
}
我们程序这样写, 无疑看出来很多弊端,我想上网,看电影,他却没有这功能,我们要怎么去做,我们重新设计程序,再增加
/**
* 网卡
*
* @author LGL
*
*/
class NetCard {
public void open() {
System.out.println("打开网络");
}
public void close() {
System.out.println("关闭网络");
}
}
但是这样,还是主板的耦合性是在是太强了,不适合扩展,所以,这个程序一定不是一个好的程序我,我们重新设计,用一个标准的接口
import javax.print.attribute.standard.MediaName;
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 需求:电脑运行实例,电脑运行基于主板
*/
MainBoard m = new MainBoard();
m.run();
// 没有设备,有设备的话之类传进去
m.userPCI(null);
}
}
/**
* 扩展接口
*
* @author LGL
*
*/
interface PCI {
public void open();
public void close();
}
/**
* 主板
*
* @author LGL
*
*/
class MainBoard {
public void run() {
System.out.println("主板运行了");
}
public void userPCI(PCI p) {
if (p != null) {
p.open();
p.close();
} else {
System.out.println("没有设备");
}
}
}
我们现在不管增加听音乐还是上网的功能,只要实现PCI的接口,就可以实现,我们现在增加一个上网功能,该怎么做?
//公共的 类 类名
public class HelloJJAVA {
// 公共的 静态 无返回值 main方法 数组
public static void main(String[] str) {
/**
* 需求:电脑运行实例,电脑运行基于主板
*/
MainBoard m = new MainBoard();
m.run();
// 没有设备
m.userPCI(null);
// 有设备
m.userPCI(new NetCard());
}
}
/**
* 扩展接口
*
* @author LGL
*
*/
interface PCI {
public void open();
public void close();
}
/**
* 主板
*
* @author LGL
*
*/
class MainBoard {
public void run() {
System.out.println("主板运行了");
}
public void userPCI(PCI p) {
if (p != null) {
p.open();
p.close();
} else {
System.out.println("没有设备");
}
}
}
/**
* 网卡
*
* @author LGL
*
*/
class NetCard implements PCI {
public void open() {
System.out.println("打开网络");
}
public void close() {
System.out.println("关闭网络");
}
}
这样我们运行
现在的主板是不是扩展性特别强,这就是多态的扩展性
OK,我们本节的篇幅就先到这里,如果感兴趣的话,可以加群:555974449
JAVA之旅(八)——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例的更多相关文章
- java学习(二)多态中成员变量详解
今天我总结了一下java多态中成员变量的赋值与调用 举一个我当初做过的小案例: class Fu{ int num; void show(){} } class Zi extends Fu{ //in ...
- 谈谈java中成员变量与成员方法继承的问题
谈谈java中成员变量与成员方法继承的问题 关于成员变量和成员方法的的继承问题,我也可以做一个小测试,来看看结果. 首先我们先创建一个父类:
- C#的HttpModule中及Java的Servlet中成员变量乱用导致的不易重现的BUG
3年前写的在HttpModule中记录访问日志的代码,在最近使用日志数据分析登录账号的IP情况时,才发现了一个不易重现的BUG——日志中记录的登录账号出现串掉的情况.之所以这个时候才发现该问题,是因为 ...
- java中成员变量,局部变量,静态变量的辨析
转自百度:https://baijiahao.baidu.com/s?id=1625360816541592483&wfr=spider&for=pc 1.java中成员变量,局部变量 ...
- java接口中成员变量和方法的默认修饰符(转)
Java的interface中,成员变量的默认修饰符为:public static final 所以我们在interface中定义成员变量的时候,可以 1:public static final St ...
- Java中成员变量和局部变量的区别
java面向对象过程中,最基本的两类变量就是成员变量和局部变量 成员变量是写在类中并且写在方法外部,一般写在每个类的头部,用于初始化或者方法操作,作用域是整个类被实例化到被销毁,中间变量都可以被外部方 ...
- java继承关系中成员变量,构造方法,成员方法的关系
Java继承中的成员关系 A:成员变量 a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单写那个名字就访问那个名字! b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢? 子 ...
- [ 转载 ] Java中成员变量 和局部变量
java语言支持的变量类型 类变量:独立于方法之外的变量,用 static 修饰. 局部变量:类的方法中的变量. 实例变量(全局变量):独立于方法之外的变量,不过没有 static 修饰. publi ...
- java中成员变量、代码块、构造函数运行顺序
1.java虚拟机执行程序,首先须要装载类,安装现装载父类,初始化父类的静态代码块和静态成员变量 再load子类. 初始化子类静态代码块和成员变量 2.load完成父类与子类后,从main函数入口运行 ...
随机推荐
- Spring boot 整合 Mybatis + Thymeleaf开发web(二)
上一章我把整个后台的搭建和逻辑给写出来了,也贴的相应的代码,这章节就来看看怎么使用Thymeleaf模板引擎吧,Spring Boot默认推荐Thymeleaf模板,之前是用jsp来作为视图层的渲染, ...
- Linux 虚存 linux2.6内核特性
一.大型页面的支持 当代计算机体系结构大都支持多种页面大小,例如,IA-32体系结构支持4KB或4MB的页面, Linux操作系统只是将大型页面用于映射实际的内核映像.大型页面的使用主要是为了改进高性 ...
- 在vs2013上的编译tesseract-ocr
在vs2013上的编译tesseract-ocr OCR(Optical Character Recognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程. Tesserac ...
- UE4使用UMG接口操作界面
原文链接:http://gad.qq.com/article/detail/7181131 本文首发腾讯GAD开发者平台,未经允许,不得转载 UE4的蓝图之强大让人欲罢不能,但是实际在项目的开发中,C ...
- EasyUI常用组件(基础)
---------------------------------------------------------------------------------------------------- ...
- ios开发之xcode环境介绍
作为一个刚入门ios开发的人来说,对于ios开发,对于xcode一切都是那么的陌生,那么我们如何开始我们的第一步呢?首先对开发的ide是必须要了解的,其实要对开发的语言要慢慢熟悉起来,今天我们先来熟悉 ...
- Hazelcast集群原理分析
简介 hazelcast其中一个很重要的应用就是可以将多个应用服务器组成一个分布式环境的应用,形成一个cluster.这个cluster可以选举出一个master来对外工作.而cluster中的各台服 ...
- CVS简介
CVS - Concurrent Versions System(并发版本管理系统)是一个版本控制管理系统,它是SVN出现之前最为广泛使用的一个版本控制系统. CVS的优点就不多说了,总之没有它,早期 ...
- JAVA面向对象-----接口的概述
接口的概述 **接口(interface):**usb接口,主要是使用来拓展笔记本的功能,那么在java中的接口主要是使用来拓展定义类的功能,可以弥补java中单继承的缺点. class Pencil ...
- everything of people’s life can changed in their twenties
还记得三年前,独自背着行李,流浪远方,来到曾经只在地理课本上才熟悉的北国,带着好奇,带着期望,带着激动的心情,想感受毛爷爷当年霸气的北国风光,千里冰封的美丽,想知道北方的面条到底有多少种花样,想走进那 ...