多态是某一事物,在不同时刻体现出来的不同的状态

就比如猫,狗,狼都是动物,我们可以说猫是动物,说狗是动物
但我们不能说动物是猫,动物是狼。也不能说猫是狗,或者狗是狼。
上面这几点都会在多态中体现出来

多态的前提:

  1. 类之间要有继承的关系
  2. 子类要有对父类方法的重写(不重写也不会报错,但这样体现不出来多态的意义)
  3. 父类的引用变量指向子类对象

下面看一个多态的简单例子

class Animal{public void eat(){System.out.println("动物要进食");}
}class Cat extends Animal{public void eat(){System.out.println("猫咪要吃饭");}
}public class Demo1 {public static void main(String[] args) {//从右往左念,猫咪是动物//new Cat()已经创建了一个Cat类的对象,在堆内存之中//Animal类的引用变量指向了Cat类的子类对象Animal a = new Cat();//这里会优先调用子类的重写方法a.eat();}
}

结果为

这里需要注意的是,虽然是父类的引用变量,但实际上调用eat()方法时,调用的是子类重写后的eat()方法

如果对重写不了解的话,可以看下面链接里面的博客
继承里面的重写问题

多态访问成员特点
1、成员变量
编译看左边,运行看左边
2、构造方法
创建子类对象的时候,先访问父类的构造方法,先对父类的数据进行初始化
3、成员方法
编译看左边,运行看右边
因为子类的成员方法存在重写,所以运行访问的时候看右边
4、静态的成员方法:
编译看左边,运行看左边
静态的随着类的加载而加载
由于被static修饰的都是与类有关系的,所以它算不上重写
所以,编译的时候看左边,运行访问的时候也看左边

这里的左边指的是父类的引用变量,右边指的是子类的对象

这个单独看文字比较难懂,所以下面还是要看几个例子
首先是第一条,成员变量,编译看左边,运行看左边

class Animal{int num =10;public void eat(){System.out.println("动物要进食");}
}class Cat extends Animal{int num = 20;public void eat(){System.out.println("猫咪要吃饭");}
}public class Demo1 {public static void main(String[] args) {Animal a = new Cat();System.out.println(a.num);}
}

输出结果为 10
编译和运行都看左边的意思是,输出的结果根据父类的属性值来定,而不是子类

然后是第二条,可以看这篇博客的后半部分,关于构造方法调用顺序的详细解释
关于构造方法调用顺序的详细解释

第三条成员方法,编译看左边,运行看右边

package test1;
class Father1{public Father1() {}public void show(){System.out.println("父类的show方法");}
}class Son1 extends Father1{public Son1() {}public void show(){System.out.println("子类的show方法");}
}
public class duotaiDemo3 {public static void main(String[] args) {Father1 f = new Son1();f.show();}
}

结果为

而当子类没有重写这个方法时,会从父类中继承该方法,然后调用该方法

package test1;
class Father1{public Father1() {}public void show(){System.out.println("父类的show方法");}
}class Son1 extends Father1{public Son1() {}
//    public void show(){//        System.out.println("子类的show方法");
//    }
}
public class duotaiDemo3 {public static void main(String[] args) {Father1 f = new Son1();f.show();}
}

编译看左边的意思是编译过程中看父类中是否有这个方法
运行看右边的意思是运行过程中实际调用的方法是子类中重写后的方法

第四条静态的成员方法

package review;
class Animal{int num =10;public void eat(){System.out.println("动物要进食");}public static void sleep(){System.out.println("动物要休息");}
}class Cat extends Animal{int num = 20;public void eat(){System.out.println("猫咪要吃饭");}public static void sleep(){System.out.println("猫咪要睡觉");}
}public class duotaiDemo {public static void main(String[] args) {Animal a = new Cat();a.sleep();System.out.println("------------");Animal.sleep();Cat.sleep();}
}

结果为

用对象调用时,调用的是父类的静态成员方法
用类名调用时,都是打印相对应的结果

介绍完多态访问成员的特点后,我们需要思考一个问题,为什么要使用,以及使用多态有什么好处
下面来看这个例子

class Animal{public void eat(){System.out.println("动物要进食");}public void sleep(){System.out.println("动物要休息");}
}class Cat extends Animal{public void eat(){System.out.println("猫咪要吃饭");}public void sleep(){System.out.println("猫咪要睡觉");}
}class Dog extends Animal{public void eat(){System.out.println("狗要啃骨头");}public void sleep(){System.out.println("狗要打盹");}
}public class Demo1 {public static void main(String[] args) {Cat c = new Cat();c.eat();c.sleep();Dog d = new Dog();d.eat();d.sleep();}
}

这里发现,如果输出猫和狗的实例对象的eat和sleep方法的结果,就需要分别用Cat类的对象c来调用,用Dog类的对象d来调用。这里是因为对象较少,调用的方法也只有eat和sleep两个方法,所以看起来还算简洁。

但如果我要创建十只猫的实例呢?要c1.eat(),c2.sleep()……这样一直调用下去吗?
那如果我不止猫和狗两种动物呢?我还要写狼的类,写豹子的类,写大象的类,都继承Animal类,然后输出这些类的对象调用方法的结果。

这时就会发现,代码的调用方法部分将变得非常冗长,有没有一种办法,可以让我们不需要用实例对象一个一个的调用方法呢?
这时候我们就需要用到多态了。而我们需要做的事情,就是创建对象,并且将对象作为参数传入一个工具类中,工具类里面会定义各种需要调用的方法。

class Animal{public void eat(){System.out.println("动物要进食");}public void sleep(){System.out.println("动物要休息");}
}class Cat extends Animal{public void eat(){System.out.println("猫咪要吃饭");}public void sleep(){System.out.println("猫咪要睡觉");}
}class Dog extends Animal{public void eat(){System.out.println("狗要啃骨头");}public void sleep(){System.out.println("狗要打盹");}
}class Bird extends Animal{public void eat(){System.out.println("鸟儿吃虫子");}public void sleep(){System.out.println("鸟儿休憩");}
}
class AnimalTools {//private的作用是让外面无法创建AnimalTools类的对象,只能使用这里面的方法private AnimalTools() {}public static void funAnimal(Animal animal){animal.eat();animal.sleep();}
}
public class Demo1 {public static void main(String[] args) {Cat c = new Cat();Dog d = new Dog();Bird b = new Bird();AnimalTools.funAnimal(c);AnimalTools.funAnimal(d);AnimalTools.funAnimal(b);Cat c2 = new Cat();AnimalTools.funAnimal(c2);}
}

结果为

多态的好处:
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)

Java学习笔记——多态(实例详解)相关推荐

  1. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示: 1.1 首行加上/usr/bin/expect 1.2 spawn: 后面加上需要执行的shell命令,比如说 ...

  2. (JAVA学习笔记) static关键字详解

    静态方法,静态变量 //static public class Studnet {private static int age; //静态的变量 可以直接调用private double score; ...

  3. expect学习笔记及实例详解

    转载自: http://ifis.blog.hexun.com/44587020_d.html 1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示: 1.1 首行加 ...

  4. Java中大数据数组,Java基础学习笔记之数组详解

    摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...

  5. ELK学习笔记之Logstash详解

    0x00 Logstash概述 官方介绍:Logstash is an open source data collection engine with real-time pipelining cap ...

  6. oracle scn 重置,学习笔记:Oracle SCN详解 SCN与Oracle数据库恢复的关系

    天萃荷净 分享一篇关于Oracle SCN的详解,介绍SCN与Oracle数据库恢复的关系和SCN在数据库中的作用 一.为什么需要System checkpoint SCN号与Datafile Che ...

  7. tcp网络通信教程 java_基于java TCP网络通信的实例详解

    JAVA中设计网络编程模式的主要有TCP和UDP两种,TCP是属于即时通信,UDP是通过数据包来进行通信,UDP当中就会牵扯到数据的解析和传送.在安全性能方面,TCP要略胜一筹,通信过程中不容易出现数 ...

  8. Java并发编程最佳实例详解系列

    Java并发编程最佳实例详解系列: Java并发编程(一)线程定义.状态和属性 Java并发编程(一)线程定义.状态和属性 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中, ...

  9. java中将json字符串_Java中JSON字符串与java对象的互换实例详解

    在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级的数据格式比xml效率要高,XML需要很多的标签,这无疑占据了网络流量,JSON在这方面则做的很好, ...

  10. Java中JSON字符串与java对象的互换实例详解

    这篇文章主要介绍了在java中,JSON字符串与java对象的相互转换实例详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JS ...

最新文章

  1. vue 企业发展历程动画_「咻动画」企业宣传片可以在哪些方面应用?
  2. 逆向链表c语言 abcdef,6-6 求单链表元素序号 (5 分)
  3. C语言再学习 -- vim常用快捷键(转)
  4. OpenCV遮罩相机的实例(附完整代码)
  5. React Native 加载多类型布局的实现——分类列表SectionList的封装
  6. STM32 解析futaba S-bus协议
  7. python打造excel神器_超简单:用Python让Excel飞起来
  8. 庖丁解牛TLD(二)——初始化工作(为算法的准备)
  9. lambda 对象去重_采用java8 lambda表达式 实现 java list 交集 并集 差集 去重复并集...
  10. matlab 8点fft蝶形图,FFT快速傅里叶变换(蝶形算法)详解精要.ppt
  11. 一二线城市知名 IT 互联网公司名单公布!
  12. DWF低代码开发技术及其在数字化运营和运维平台建设中的应用
  13. NGUI|如何做出用鼠标滚动切换武器的效果
  14. iOS锁屏页面控制音乐播放
  15. 成功抗“疫”背后的IT科技
  16. Linux虚拟机无法显示IP的解决办法
  17. 认识VF--Visual FoxPro 漫谈
  18. 打印机文件里没有服务器属性,win7没有打印机服务器属性设置
  19. Doo Prime 德璞资本:标普500期货交易小知识,看懂影响价格走势的因素
  20. [转]一个纸杯的测试用例

热门文章

  1. 专访阿里巴巴移动安全负责人陈树华:安全的最高境界是无感知
  2. linux 下python进程查看及关闭
  3. Ps制作信号干扰故障风艺术效果动图
  4. 预测和分类钻孔的毛刺钻孔切削ANN预测
  5. Discuz的模板制作与源代码分析
  6. 油管 在股票交易中学习
  7. 生成一个vba,筛选G列,取消全选和空白,点击筛选
  8. ES6基础-ES6的扩展
  9. 苹果亮度突然变暗_苹果手机耗电太快?学会关闭这几个设置,让你告别一天三充...
  10. b550和x570主板区别