Java基础-面向对象第三大特性之多态(polymorphism)

作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.多态概述

多态是继封装,继承之后,面向对象的第三大特性,多态的前提是继承。

从现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三即是学生也是人。即出现两种形态。Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

最终多态体现为父类引用变量可以指向子类对象。多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

二.多态调用的三种形式

多态调用方法,方法必须运行子类的重写!

1>.多态的定义格式:就是父类的引用变量指向子类对象。

1 父类类型 变量名 = new子类类型();2 变量名.方法名();

2>.普通类多态定义的格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classFather{8 public voidshow(){9 System.out.println("父类的show方法!");10 }11 }12

13 class Son extendsFather{14 public voidshow(){15 System.out.println("子类重写父类的show方法!");16 }17 }18

19 public classMyInterfaceDemo{20 public static voidmain(String[] args){21 //Java中,对象的多态性,调用公式:“父类类型或者接口类型 变量 = new 子类对象();”

22 Father f = newSon();23 f.show();24 }25 }26

27

28

29 /*

30 以上代码执行结果如下:31 子类重写父类的show方法!32 */

3>.抽象类多态定义的格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classFather{8 public abstract voideat();9 }10

11 class Son extendsFather{12 public voideat(){13 System.out.println("儿子喜欢吃米饭!");14 }15 }16

17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //抽象类Father,子类是Son

20 Father f = newSon();21 f.eat();22 }23 }24

25

26

27 /*

28 以上代码执行结果如下:29 儿子喜欢吃米饭!30 */

4>.接口多态定义格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 interfaceFather{8 public abstract voidsmoking();9 }10

11 class Son implementsFather{12 public voidsmoking(){13 System.out.println("儿子会抽烟!");14 }15 }16

17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //接口Father,实现类Son

20 Father f = newSon();21 f.smoking();22 }23 }24

25

26

27 /*

28 以上代码执行结果如下:29 儿子会抽烟!30 */

三.多态中成员变量的特点

1>.成员变量(编译运行全看父类)

a>.编译的时候,参考父类中有没有这个变量,如果有,编译成功,没有则编译失败;

b>.运行的时候,运行的是父类中的变量值;

2>.成员方法(编译看父类,运行看子类。)

a>.编译的时候,参考父类中有没有这个方法,如果有,编译成功,没有则编译失败

b>.运行的时候,运行的是子类的重写方法;

3>.静态成员方法

没有多态性。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classFather{8 int age = 30;9 public voidshow(){10 System.out.println("Father的方法");11 }12 }13

14 class Son extendsFather{15 int age = 8;16 public voidshow(){17 System.out.println("Son的方法");18 }19 }20

21 public classMyInterfaceDemo{22 public static voidmain(String[] args){23 Father f = newSon();24 System.out.println(f.age);25 f.show();26 }27 }28

29

30

31 /*

32 以上代码执行结果如下:33 3034 Son的方法35 */

四.instanceof关键字

我们了解多态之后,会发现一个对象的数据类型不一定会保持不变。当我们想要确定一个对象是否是某个类时,就会用到比较运算符,只不过它很特殊,不能赢大于小于或是等于号直接进行判断,而是要用到关键字,即instanceof,它只能用作比较引用数据类型,用来比较一个引用类型的变量,是不是这个类型的对象。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 Person p = newStudent();28

29 p = newTeacher();30

31 boolean flag = p instanceofStudent;32

33 System.out.println("引用数据类型'p'是否为Student类型:>>> " +flag);34

35 p.sleep();36 }37 }38

39

40

41

42 /*

43 以上代码执行结果如下:44 引用数据类型'p'是否为Student类型:>>> false45 老师在休息!46 */

五.多态转型

1>.多态的向上转型

多态常见的就是自动类型提升,将取值范围小的,自动提升为取值范围大的。范围小的,看成是子类,范围大的看成父类。

优点:

这样做的好出就是可以调用子类父类的公共属性(方法)。

缺点:

无法调用子类特有的属性(方法)。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 //从子类对象往父类变量赋值(自动类型提升,向上转型)

28 Person p = newStudent();29

30 }31 }

2>.多态的向下转型

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 //从子类对象往父类变量赋值(自动类型提升,向上转型)

28 Person p = newStudent();29

30

31 //从父类类型转向子类类型(向下转型)

32 Student s =(Student)p;33

34 }35 }

3>.多态转型的案例

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classAnimal{8 public abstract voideat();9 }10

11 class Cat extendsAnimal{12 public voideat(){13 System.out.println("猫吃猫粮!");14 }15

16 public voidcatchMouse(){17 System.out.println("猫抓老鼠!");18 }19 }20

21 class Dog extendsAnimal{22 public voideat(){23 System.out.println("狗吃狗粮!");24 }25

26 public voidrun(){27 System.out.println("狗能跑!");28 }29 }30

31 public classAnimalDemo{32 public static voidmain(String[] args){33 //两个子类,使用两次多态调用

34 Animal a1 = newCat();35 Animal a2 = newDog();36 //a1,a2调用子类父类共有方法,运行走子类的重写方法

37 a1.eat();38 a2.eat();39 /*类型向下转型,强制转换,调用子类的特有,防止发生异常,40 a1属于CatUI小,转成Cat类,a2属于Dog对象,转成Dog类,我们41 可以用关键字instanceof判断。42 */

43 if(a1 instanceofCat){44 Cat c =(Cat)a1;45 c.catchMouse();46 }47

48 if(a2 instanceofDog){49 Dog d =(Dog)a2;50 d.run();51 }52

53 }54 }55

56

57 /*

58 以上代码执行结果如下:59 猫吃猫粮!60 狗吃狗粮!61 猫抓老鼠!62 狗能跑!63 */

六.匿名对象

1>.匿名对象的概念

匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classPerson{8 public voideat(){9 System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");10 }11 }12

13

14 public classPersonDemo{15 public static voidmain(String[] args){16

17 //有名字的对象,引用类型变量,可以反复使用eat方法。

18 Person p = newPerson();19 p.eat();20

21 //匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。

22 newPerson().eat();23 newPerson().eat();24

25 }26 }

2>.匿名对象的特点

a>.创建匿名对象直接使用,没有变量名;

b>.匿名对象在没有指定其引用变量时,只能使用一次;

c>.匿名对象可以作为方法接受的参数,方法返回值使用;

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classPerson{8 public voideat(){9 System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");10 }11 }12 public classPersonDemo{13 public static voidmain(String[] args){14 //有名字的对象,引用类型变量,可以反复使用eat方法。

15 Person p = newPerson();16 p.eat();17 //匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。

18 newPerson().eat();19 newPerson().eat();20 method(p);21

22 //匿名方法当实参

23 method(newPerson());24 p =method();25 method(p);26 }27 //方法的返回值是Person类型,方法的return语句,返回的是这个类的对象。就可以用匿名对象来实现。

28 public staticPerson method(){29 return newPerson();30 }31 //调用方法method,传递Person类型对象

32 public static voidmethod(Person p){33 p.eat();34 }35 }36

37

38

39 /*

40 以上代码执行结果如下:41 人是铁,饭是钢,一顿不吃饿得慌!42 人是铁,饭是钢,一顿不吃饿得慌!43 人是铁,饭是钢,一顿不吃饿得慌!44 人是铁,饭是钢,一顿不吃饿得慌!45 人是铁,饭是钢,一顿不吃饿得慌!46 人是铁,饭是钢,一顿不吃饿得慌!47 */

七.内部类

1>.内部类概念

a>.什么是内部类

将类写在其它类的内部,可以写在其它类的成员位置和局部位置,这时写在其它类内部的类成为内部类,其它类也称为外部类。

b>.什么时候使用内部类

在描述事物时,若一个事物内部还包含其它可能包含的事物,比如在描述汽车时,汽车中还包含这发动机,这时发动机就可以使用内部类来描述。

c>.内部类分类

内部类分为成员内部类和局部内部类。我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符,继承与实现关系等。在内部类中可以直接访问外部类的所有成员。

2>.成员内部类的调用格式

内部类可以使用外部类成员,包括私有变量。外部类要使用内部类的成员,必须建立内部类对象。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 private int a = 100;9 classInner{10 public voidinner(){11 System.out.println("内部类方法inter " +a);12 }13 }14 }15

16 public classInnerClassDemo{17 public static voidmain(String[] args){18 //创建内部类对象in

19 Outer.Inner in = new Outer().newInner();20 //调用内部类方法

21 in.inner();22 }23 }24

25

26 /*

27 以上代码执行结果如下:28 内部类方法inter 10029 */

3>.成员内部类的同名变量调用

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 int a = 100;9 classInner{10 int a = 200;11 public voidinner(){12 int a = 300;13 System.out.println("内部类局部变量(内部类成员方法)访问:>>> "+a);14 System.out.println("内部类成员变量访问:>>> "+ this.a);15 System.out.println("外部类成员变量访问:>>> "+ Outer.this.a);16 }17 }18 }19

20 public classInnerClassDemo{21 public static voidmain(String[] args){22 //创建内部类对象in

23 Outer.Inner in = new Outer().newInner();24 //调用内部类方法

25 in.inner();26 }27 }28

29

30 /*

31 以上代码执行结果如下:32 内部类局部变量(内部类成员方法)访问:>>> 30033 内部类成员变量访问:>>> 20034 外部类成员变量访问:>>> 10035 */

3>.局部内部类

局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 public voidout(){9 classInner{10 public voidinner(){11 System.out.println("局部内部类方法!");12 }13 }14 //创建我们定义的Inner对象

15 Inner in = newInner();16 //调用创建好的对象的方法,这样不管谁只要能调用out方法就会触发调用Inner类中的inner()方法啦!

17 in.inner();18 }19 }20

21 public classInnerClassDemo{22 public static voidmain(String[] args){23 newOuter().out();24 }25 }26

27

28 /*

29 以上代码执行结果如下:30 局部内部类方法!31 */

4>.匿名内部类

a>.匿名内部类概念

内部类是为了应对更为复杂的类间关系。查看源代码中会涉及到,而在日常业务中很难遇到,这里不做赘述。最长用到的内部类就是匿名内部类,它是局部内部类的一种。定义的匿名内部类有两个含义:第一,临时定义某一指定类型的子类;第二,定义后即刻创建刚刚定义的这个子类的对象。

b>.定义匿名内部类的作用与格式

匿名内部类是创建某个子类对象的快捷方式。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 interfaceSmoking{8 public abstract voidsmoking();9 }10

11 public classSmokingDemo{12 public static voidmain(String[] args){13 //这就是用匿名对象实现接口并调用接口中的方法,切记不要忘记调用smoking()了哟!

14 newSmoking(){15 public voidsmoking(){16 System.out.println("运维不喜欢吸烟!");17 }18 }.smoking();19 }20 }21

22 /*

23 以上代码执行结果如下:24 运维不喜欢吸烟!25 */

polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)相关推荐

  1. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

  2. 面向对象的三大特性之多态

    面向对象的三大特性之多态 文章目录 面向对象的三大特性之多态 前言 一.静态多态 1.函数重载 2.函数模板 二.动态多态 1.函数重写 2.虚函数的继承特性 三.重定义 前言 多态的简单定义为同一种 ...

  3. 面向对象的三大特性之多态,封装基础

    面向对象的三大特性  :  继承    多态    封装 多态:一个类表现出多种形态:通过继承来实现的 在python中:由于函数的参数不需要指定数据类型,所以也不需要通过继承的形式来统一一组类的类型 ...

  4. C++ 面向对象程序三大特性之 多态

    目录 多态的概念 多态的定义及使用 虚函数 虚函数的重写 虚函数重写的两个例外 C++11中 override 和 final 重载.重写.隐藏的区别与联系 抽象类 多态的原理 虚函数指针.虚函数.虚 ...

  5. Python面向对象编程三大特性之多态

    多态 code:_9polymorphism.py # ***************************************** """ 多态:对于同一个方法, ...

  6. C++ 面向对象程序三大特性之 继承

    目录 继承的概念 继承的定义及使用 继承方式和访问权限 基类和派生类对象的赋值转换 继承中的各成员的作用域 派生类的默认成员函数 构造函数 拷贝构造 赋值运算符重载函数 析构函数 继承与友元 继承与静 ...

  7. python基础学习笔记13:面向对象的三大特性

    1.面向对象有哪些特性 面向对象的三大特性:封装性.继承性.多态性 2.Python中的封装 在Python代码中,封装有两层含义: 把现实世界中的主体中的属性和方法书写到类的里面的操作即为封装 cl ...

  8. 到底什么是面向对象,面试中怎么回答。面向过程和面向对象的区别是什么。java跨平台特性以及java和C++的区别。面向对象的三大特性——封装、继承和多态。面向对象的高拓展性以及低耦合度怎么体现?

    Java语言具有的特点:面向对象.跨平台.多线程以及网络编程 1. 和C++的区别 1.1 Java隐蔽了C++的指针,避免指针直接操作,程序更加安全. 1.2 Java类继承只能单继承,避免了C++ ...

  9. 面向对象之三大特性:继承,封装,多态

    python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分 ...

最新文章

  1. RAP、Mock.js、Vue.js、Webpack
  2. 函数模块:CTVB_COMPARE_TABLES
  3. 15个PHP库,你值得拥有!(下)
  4. delphi frame 添加 create onshow 事件
  5. push_back还是emplace_back?
  6. 智能门禁(4)---基于face++和Onenet平台的人脸门禁系统
  7. sass笔记 - 实战中颜色的玩法总结
  8. OSChina 周三乱弹 —— 九招助你工资秒长(干货哟)
  9. iOS多控制器-视图切换.
  10. uptime查看服务器负载详解
  11. c语言输入字母 字母表,输入字符,如果是字母则汇报并返回字母在字母表中序号的程序...
  12. python清屏幕_如何在python中清除屏幕?
  13. 飞信登录时SIPC认证失败解决
  14. 【JavaWeb】JSP:基本语法大全
  15. R语言data.table包进行数据分组聚合统计变换(Aggregating transforms)、计算dataframe数据的分组四分位距(interquartile range, IQR)
  16. java中获取中文拼音(全拼)和中文首字母
  17. 攻与防--论游戏好玩的本质
  18. c语言字节溢出,C语言变量定义与数据溢出(初学者)
  19. python编写的软件可以申请专利吗_Python爬虫 | 爬取同一公司用不同名字申请专利的那些Assignees...
  20. 免费网站seo诊断:从哪些维度进行诊断呢?

热门文章

  1. 数据结构之二叉搜索树
  2. 使用C与C++混合编程封装UDP协议
  3. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 19丨行转列【难度中等】​
  4. 小甲鱼 OllyDbg 教程系列 (十六) : 简单病毒的逆向分析
  5. linux 升级java_linux 升级jdk1.8
  6. java jvm对象_Java对象在JVM中长啥样
  7. linux建立动态库链接,Linux动态链接库.so文件的创建与使用
  8. 关于数据库备份的问题
  9. 软件项目周报_有关细节、效率、周报和扯淡
  10. linux ofstream open,浅谈linux性能调优之十一:内存分配管理