Java——面向对象的特征三:多态性
2.5面向对象的特征三:多态性
2.5.1 关于java语言中的向上转型和向下转型
①向上转型(upcasting) : 子--->父(自动类型转换)
②向下转型(downcasting) : 父--->子(强制类型转换)
注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系。
|
public class Animal{ //成员 public void eat(){ System.out.println("动物在吃!"); } } |
|
public class Cat extends Animal{ //重写 public void eat(){ System.out.println("猫吃鱼"); } //Cat特有的方法. public void move(){ System.out.println("猫走猫步!"); } } |
|
public class Test02{ public static void main(String[] args){ //向上转型又被称作:自动类型转换. //父类型的引用指向子类型对象. //程序分两个阶段:编译阶段,运行阶段。 //程序编译阶段只知道a1是一个Animal类型。 //程序在运行的时候堆中的实际对象是Cat类型。 Animal a1 = new Cat(); //程序在编译阶段a1被编译器看做Animal类型. //所以程序在编译阶段a1引用绑定的是Animal类中的eat方法.(静态绑定) //程序在运行的时候堆中的对象实际上是Cat类型,而Cat已经重写了eat方法。 //所以程序在运行阶段对象的绑定的方法是Cat中的eat方法.(动态绑定) a1.eat(); //猫吃鱼 //向下转型:强制类型转换 Animal a2 = new Cat(); //向上转型. //要执行move方法,怎么做? //只能强制类型转换,需要加强制类型转换符 Cat c1 = (Cat)a2; c1.move(); //判断以下程序运行的时候会出什么问题? //Animal a3 = new Dog(); //向上转型. //强制类型转换 //Cat c2 = (Cat)a3; // java.lang.ClassCastException //在做强制类型转换的时候程序是存在风险的! //为了避免ClassCastException的发生,java引入了 instanceof /* 用法: 1. instanceof运算符的运算结果是 boolean类型 2. (引用 instanceof 类型) --> true/false 例如:(a instanceof Cat) 如果结果是true表示:a引用指向堆中的java对象是Cat类型. */ Animal a3 = new Dog(); System.out.println(a3 instanceof Cat); //false //推荐:在做向下转型的时候要使用instanceof运算符判断,避免ClassCastException if(a3 instanceof Cat){ Cat c2 = (Cat)a3; } } } |
2.5.2 什么是多态
多态性,可以理解为一个事物的多种表型形态,是面向对象中最重要的概念,在java中有两种体现:
①方法的重载(overload)和重写(overwrite)。
②子类对象的多态性:并不适用于属性。调用属性是就看”.”左边的对象。可以直接应用在抽象类和接口上。
2.5.3 子类对象的多态性使用的前提
①要有类的继承
②要有子类对父类方法的重写
补充:
①程序运行分为编译状态和运行状态。
对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型;运行时,"看右边",关注于真正对象的实体:子类的对象。那么执行的方法就是子类重写的。
②Java引用变量有两个类型:编译时类型和运行时类型。
编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。若编译时类型和运行时类型不一致,就出现多态(Polymorphism)
2.5.4 对象的多态
在Java中,子类的对象可以替代父类的对象使用
①一个变量只能有一种确定的数据类型
②一个引用类型变量可能指向(引用)多种不同类型的对象
|
Person p = new Student(); Object o = new Person();//Object类型的变量o,指向Person类型的对象 o = new Student(); //Object类型的变量o,指向Student类型的对象 |
③子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。
④一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。
|
Student m = new Student(); m.school = “pku”; //合法,Student类有school成员变量 Person e = new Student(); e.school = “pku”; //非法,Person类没有school成员变量 //属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。 |
2.5.5 多态的好处
①使用多态可以使代码之间的耦合度降低。②项目的扩展能力增强。
例子:人喂养宠物
|
public class Person{//模拟主人 /* public void feed(Dog d){ //喂养 d.eat(); } public void feed(Cat c){ //因为用户的业务改变了,所以软件要升级。 c.eat(); } */ //以上的代码得出:Person类型的扩展能力太差。 //尽量不要面向具体编程,面向父类型编程,面向抽象编程 public void feed(Animal a){ a.eat(); } } |
|
public class Animal{ public void eat(){} } |
|
public class Cat extends Animal{//宠物1 public void eat(){ System.out.println("猫吃东西!"); } } |
|
public class Dog extends Animal{//宠物2 public void eat(){ System.out.println("狗吃东西!"); } } |
|
public class Test{//多态测试 public static void main(String[] args){ //1.创建主人 Person zhangsan = new Person(); //2.创建宠物 Dog d = new Dog(); Cat c = new Cat(); //3.喂 zhangsan.feed(d); zhangsan.feed(c); } } |
2.5.6 虚拟方法调用(Virtual Method Invocation)
①正常的方法调用
|
Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo(); |
②虚拟方法调用(多态情况下)
|
Person e = new Student(); e.getInfo(); //调用Student类的getInfo()方法 |
编译时类型和运行时类型:
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
多态小结
1.前提:
- 需要存在继承或者实现关系
- 要有覆盖操作
2.成员方法:
- 编译时:要查看引用变量所属的类中是否有所调用的方法。
- 运行时:调用实际对象所属的类中的重写方法。
3.成员变量:不具备多态性,只看引用变量所属的类。
【记忆】
虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法。
例子:有一个舞池,规定只有人能进入,动物不能进,这时一个男人进去了,是以人的身份,但是跳舞的时候是一个男人的姿势!即调用的方法是那个实体的方法!
1)多态性的表现:①方法的重载与重写 ②子类对象的多态性
2)使用的前提:①要有继承关系 ②要有方法的重写
3)格式:
|
Person p = new Man();//向上转型 // 虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法 p1.eat(); p1.walk(); // p1.entertainment(); |
4)编译时,认为p是Person类型的,故只能执行Person里才有的结构,即Man里特有的结构不能够调用。子类对象的多态性,并不使用于属性。
5)关于向下转型:
①向下转型,使用强转符:()
②为了保证不报ClassCastException,最好在向下转型前,进行判断: instanceof
|
// 若a是A类的实例,那么a也一定是A类的父类的实例。 // 格式: 对象a instanceof 类A:判断对象a是否是类A的一个实例.是的话,返回true;否则返回false if (p1 instanceof Woman) { System.out.println("hello!"); Woman w1 = (Woman) p1; w1.shopping(); } if (p1 instanceof Man) { Man m1 = (Man) p1; m1.entertainment(); } |

Java——面向对象的特征三:多态性的更多相关文章
- Java面向对象 IO (三)
Java面向对象 IO (三) 知识概要: (1)IO 流的操作规律 (2)异常日志信息IO处理 ...
- 【重走Android之路】【Java面向对象基础(三)】面向对象思想
[重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想 1 面向对象的WWH 1.1 What--什么是面向对象 首先,要理解“对象”.在Thinkin ...
- Java面向对象的特征
面向对象的特征 封装.继承.多态.(有人问第四个特征,再加抽象) 封装 体现形式(2种) 函数---提高代码的复用性 属性的私有化---将属性设置为私有的,通过提供对外的访问方法来间接操作对应属性,可 ...
- Java——面向对象的特征二:继承性
2.1面向对象的特征二:继承性 ①引入类继承最基本的作用是:代码重用. ②语法 [修饰符列表] class 子类名 extends 父类名{ 类体; } ③子类继承父类以后,父类中声明的属性.方法,子 ...
- Java面向对象的特征一:封装性
1.4 面向对象的特征一:封装性 当创建了类的对象以后,如果直接通过"对象.属性"的方式对相应的对象属性赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而 ...
- java 面向对象(十五):面向对象的特征三:多态性
1.多态性的理解:可以理解为一个事物的多种形态.2.何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)举例:Person p = new Man();Object obj ...
- 封装继承多态-java面向对象三大特征
第七章 封装和继承 一.面向对象的三大特征 封装.继承.多态 二.封装 将类的属性(字段)设置为私有的(private),并添加getter/setter方法操作属性. 注意:get|set方法的固 ...
- Java面向对象和特征
面向对象: 概念: 面向对象是一种程序设计思想,计算机程序的设计实质上就是将现实中的一些事物的特征抽离出来描述成一些计算机事件的过程,这种抽象的过程中,我们把具体的事物封装成一个一个的整体进行描述,使 ...
- Java面向对象三大特征
封装: 首先,属性可用来描述同一类事物的特征, 行为可描述一类事物可做的操作,封装就是要把属于同一类事物的共性(包括属性与行为)归到一个类中,以方便使用.比如人这个东东,可用下面的方式封装:人{ 年龄 ...
随机推荐
- shell script 学习
终于来到了shell脚本的学习,貌似很牛叉. shell script鸟叔解释:利用shell的功能写的一个program,使用纯文本文件,将一些shell语法和指令写在里面,搭配正则表示法,管线命令 ...
- VS2017编译64位CloudCompare
需求:编译一个支持读写las点云的CC,然后再开发CC插件实现业务功能. 编译环境: 1.Windows 10 2.Visual Studio 2017 Community 3.Qt 5.9.4 开源 ...
- Mate Translate的特色功能phrasebook 常用语手册介绍
Mate Translate是Mac os系统上一款多国语言即时翻译工具,支持103种语言之间的即时互译,还可以在你的所有设备之间轻松同步.Mate Translate 不但推出了适应各个平台使用的客 ...
- Dart编程实例 - Enabling Checked Mode
Dart编程实例 - Enabling Checked Mode void main() { int n="hello"; print(n); } 本文转自:http://codi ...
- 阿里云HBase全新发布X-Pack NoSQL数据库再上新台阶
一.八年双十一,造就国内最大最专业HBase技术团队 阿里巴巴集团早在2010开始研究并把HBase投入生产环境使用,从最初的淘宝历史交易记录,到蚂蚁安全风控数据存储.持续8年的投入,历经8年双十一锻 ...
- vue笔记一:设置表头的背景颜色以及下边框颜色
最近做的一个项目有个小小的需求,就是把表头的背景颜色改为黑色,表格边框颜色改为这个颜色,中间出了些问题,因为vue的表格样式是内联样式,一修改就影响到其他地方的表格样式,尽管我单独加了id还是不行,经 ...
- noip2002 普及组 过河卒
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过 ...
- js检查判断设备
js检查判断设备 var navigatorType = {}; var u=navigator.userAgent; navigatorType.IsIE= u.indexOf('Trident') ...
- 配置Maven私服
Nexus 是“开箱即用”的系统,不需要数据库,它使用文件系统加 Lucene 来组织数据,支持 WebDAV 与 LDAP 安全身份认证.Nexus 还提供了强大的仓库管理功能,构件搜索功能,它基于 ...
- Karaf基础知识
Karaf 遵循OSGi开发规范的一个Apache框架 1.命令形如:scope:name 举例:feature:list 2 shell:completion tab键补齐 GLOBAL 补齐显 ...