1、多态的介绍
多态(Polymorphism)按字面意思理解就是“多种形态”,即一个对象拥有多种形态。
即同一种方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
多态存在的条件
- 有继承(基类)或 实现 (接口) 关系
- 子类重写父类的方法
- 父类引用变量指向子类对象
==注:==多态是针对实例方法的多态,不是属性的多态,也不是类方法的多态。
java 引用变量分为两种类型,一种是编译时类型,一种是运行时类型。
编译时类型由声明该变量时使用的类型决定;运行时类型由实际赋值给该变量的对象决定。
如果编译时类型和运行时类型不一致,就**可能(重写了方法的话)**出现所谓的多态。
class Person {
public void eat() {
}
}
class Student extends Person {
// 重写了基类中的方法
public void eat() {
}
// 子类中特有的方法
public void study() {
}
}
class Applicaton {
public static void main(String[] args) {
// 不存在多态 编译时类型和运行时类型一致
Student s3 = new Student();
// 不存在多态 编译时类型和运行时类型一致
Person s2 = new Person();
// 存在多态 编译时类型和运行时类型不一致,重写了基类中的方法
Person s1 = new Student();
s1.eat();
// 报错 原因下方会解释
// s1.study();
}
}
当把一个子类对象直接赋值给父类引用变量时:
例如上面的 Person s1 = new Student();
这个 s1 的引用变量的编译类型是 Person,而运行时类型是 Student,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现:相同类型的变量调用同一个方法时呈现出多种不同的行为特征,这就是多态。
这里的相同类型就是指同一个引用变量(s1),调用同一个方法,但指向不同的子类对象时,表现出不同的行为特征。
注:
1、通过引用变量来直接访问其包含的实例变量时,系统总是试图访问它编译时类型定义的实例变量,而不是运行时类型所定义的实例变量。
2、引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行阶段则可以调用它运行时类型所具有的的方法。
还是上面的例子:Person s1 = new Student();
s1 引用变量只能调用 Person 类的方法,不能直接调用 Student 里独有的方法。
作用
简单来说,就是建立一个父类对象的引用变量,指向不同的子类对象。
把不同的子类对象都当做父类来看待,屏蔽不同子类对象之间的差异,写出通用的代码,以适应需求的不断变化。
而且无论右边 new 的时候换成了哪个子类对象,等号左边的调用方法都不会变化。
2、多态的格式
- 代码当中体现多态性,其实就是一句话:父类引用指向子类对象。
- 格式:
基类类型 引用变量名称 = new 子类类型(