尚硅谷JavaSE基础

6.8 基本特征三 多态

曰:“白马非马,可乎?”

曰:“可。”

曰:“何哉?”

曰:“马者,所以命形也。白者,所以命色也。命色者,非命形也,故曰白马非马。”

6.8.1 什么是多态

1. 本态

一个对象的本类形态就是本态.

2. 多态

一个对象的多种父类形态就是多态

6.8.2多态的使用

1. 多态引用

  将子类对象赋值于父类类型的引用变量就是多态引用, 在这里对象其实还是子类对象, 只不过是被看作是一个父类类型的对象.

Person person = new Student();

  • 多态性,是面向对象中最重要的概念,在java中有两种体现:
    1. 方法的重载(overload)和重写(overwrite)。
    2. 对象的多态性   ——可以直接应用在抽象类和接口上。
  • Java引用变量有两个类型:编译时类型运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。

注意:若编译时类型和运行时类型不一致,就出现多态(Polymorphism

2. 多态带来的问题

  • 一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法

Student m = new Student();

m.school = “pku”; //合法,Student类有school成员变量

Person e = new Student();

e.school = “pku”; //非法,Person类没有school成员变量

     属性是在编译时确定的,编译时ePerson类型,没有school成员变量,

因而编译错误。

6.8.3虚拟方法调用(Virtual Method Invocation)

1. 什么是虚拟方法

  正常的方法调用:

    Person e = new Person();

   e.getInfo();

   Student e = new Student();

    e.getInfo();

  虚拟方法调用(多态情况下)

   Person e = new Student();

     e.getInfo(); //调用Student类的getInfo()方法

  编译时类型和运行时类型

  编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。

  ——动态绑定

2. 多态小结

  前提:

     需要存在继承或者实现关系

  要有覆盖操作

     成员方法: 

  编译时:要查看引用变量所属的类中是否有所调用的方法。

  (编译时检查父类类型)

  运行时:调用实际对象所属的类中的重写方法。

  (运行时执行子类类型)

  成员变量:

  不具备多态性,只看引用变量所属的类。