java -- 多态

基本概念

多态的前提

  • 存在子父类继承关系(或子类和父类接口实现关系)
  • 存在方法重写
  • 父类(或父接口)引用指向子类对象

动态绑定

​ 运行期间调用的方法,是根据具体的类型决定的。

多态的成员特点

成员分类特点
成员变量编译时看的是左边,运行时看的是左边
成员方法编译时看的是左边,运行时看的是右边(动态绑定)
静态成员方法编译时看的是左边,运行时看的也是左边

举例说明

先定义父类和子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Dad {
int num = 20;

public void method() {
System.out.println("我是父类方法");
}

public static void function() {
System.out.println("我是父类静态方法");
}
}

class Kid extends Dad {
int num = 10;

public void method() {
System.out.println("我是子类方法");
}

public static void function() {
System.out.println("我是子类静态方法");
}
}

1 对于成员变量

1
2
3
4
5
6
7
8
9
10
public class PoymorphicDemo {
public static void main(String[] args) {
Dad d = new Kid();
//d.num 编译时,首先会查看父类Dad中是否存在num成员变量,如不存在,则会报错,这就是“编译看左边”
System.out.println(d.num);
}
}

//输出 20
//这就说明最后输出的是父类Dad中的成员变量,即所谓“运行看左边”

2 对于成员方法

1
2
3
4
5
6
7
8
9
10
11
public class PoymorphicDemo2 {
public static void main(String[] args) {
Dad d = new Kid();
//d.method()编译时,首先会查看父类Dad中是否存在method成员方法,不存在,就会报错,即“编译看左边”
d.method();

}
}

//输出 我是子类方法
//最后执行的是子类成员方法,即所谓的“运行看右边”,这里涉及运行期间的编译器“动态绑定”

3 对于静态成员方法

与成员变量类似,这里不在赘述。

多态中的向上转型和向下转型

本质上属于引用数据类型的转型问题。可以和基本数据类型转型进行对比

基本数据类型引用数据类型
自然转型小存储空间向大存储空间转型子类向父类转型(向上转型)
强制转型大存储空间向小存储空间转型父类向子类转型(向下转型)

说明:向上转型,只能调用父类中存在并被重写的方法;向下转型,可以调用子类中特有的方法

多态的优缺点

优点

由于多态基于继承和接口,故继承和接口所具有的优点,它都具有(如减少代码冗余,可维护,模块化编程等)

缺点

无法访问子类特有成员和方法