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——面向对象的特征三:多态性的更多相关文章

  1. Java面向对象 IO (三)

     Java面向对象  IO  (三) 知识概要:                    (1)IO 流的操作规律                    (2)异常日志信息IO处理          ...

  2. 【重走Android之路】【Java面向对象基础(三)】面向对象思想

    [重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想   1 面向对象的WWH   1.1 What--什么是面向对象         首先,要理解“对象”.在Thinkin ...

  3. Java面向对象的特征

    面向对象的特征 封装.继承.多态.(有人问第四个特征,再加抽象) 封装 体现形式(2种) 函数---提高代码的复用性 属性的私有化---将属性设置为私有的,通过提供对外的访问方法来间接操作对应属性,可 ...

  4. Java——面向对象的特征二:继承性

    2.1面向对象的特征二:继承性 ①引入类继承最基本的作用是:代码重用. ②语法 [修饰符列表] class 子类名 extends 父类名{ 类体; } ③子类继承父类以后,父类中声明的属性.方法,子 ...

  5. Java面向对象的特征一:封装性

    1.4 面向对象的特征一:封装性 当创建了类的对象以后,如果直接通过"对象.属性"的方式对相应的对象属性赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而 ...

  6. java 面向对象(十五):面向对象的特征三:多态性

    1.多态性的理解:可以理解为一个事物的多种形态.2.何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)举例:Person p = new Man();Object obj ...

  7. 封装继承多态-java面向对象三大特征

    第七章  封装和继承 一.面向对象的三大特征 封装.继承.多态 二.封装 将类的属性(字段)设置为私有的(private),并添加getter/setter方法操作属性. 注意:get|set方法的固 ...

  8. Java面向对象和特征

    面向对象: 概念: 面向对象是一种程序设计思想,计算机程序的设计实质上就是将现实中的一些事物的特征抽离出来描述成一些计算机事件的过程,这种抽象的过程中,我们把具体的事物封装成一个一个的整体进行描述,使 ...

  9. Java面向对象三大特征

    封装: 首先,属性可用来描述同一类事物的特征, 行为可描述一类事物可做的操作,封装就是要把属于同一类事物的共性(包括属性与行为)归到一个类中,以方便使用.比如人这个东东,可用下面的方式封装:人{ 年龄 ...

随机推荐

  1. accept 修改后

  2. 配置文件--spring cloud Config

    配置中心--Spring cloud Config 通过本次学习,我们应该掌握: Config Server 读取配置文 Config Server 从远程 Git 仓库读取配置文 搭建芮可用 Con ...

  3. vue-resource请求

    man.js引入 import Vue from 'vue' import VueResource from 'vue-resource' import App from './App.vue' Vu ...

  4. hdu 5792 线段树+离散化+思维

    题目大意: Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a< ...

  5. vue 2.1.3 实时显示当前时间,每秒更新

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. 上传图片,预览并保存成blob类型 和 base64

    场景: 获取到一个file类型的图片,如果直接在html中预览?这里就是利用html5的新特性,将图片转换为Base64的形式显示出来.有两种方法: 方法一:利用URL.createObjectURL ...

  7. 第十一次 LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...

  8. SQL 删除

    SQL Delete 语句(删除表中的记录) DELETE语句用于删除表中现有记录. SQL DELETE 语句 DELETE 语句用于删除表中的行. SQL DELETE 语法 DELETE FRO ...

  9. 经典排序背包——cf1203F

    先把收益为正数的处理掉:策略是挨个扫,扫n遍,碰到能买的就买,然后可以得到一个更新后的r 剩下的就看做是一个背包模型:物品(a,b)表示当背包体积>a时才能装下体积为b的该物品,问最多装几个 无 ...

  10. 最全的PS快捷键大全!

    一.工具箱 01.(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取)02.矩形.椭圆选框工具 [M]03.裁剪工具[C]04.移动工具[V]05.套索.多边形套索.磁性套索[L]06.魔 ...