一 . 概念
多态是面向对象编程的三大特性之一, 其余两个抽象和继承(参考https://blog.csdn.net/ysq_chris/article/details/80100793)。很多地方把多态的概念说的很抽象不好理解。我简单的总结理解就是:
一个父类型引用句柄可以被子类型代替,可以实现类型上溯
一个子类型对象被一个父类型的句柄所引用。
1. 先理解一下绑定这个概念
将一个方法调用同该方法所在的主体进行一对一关联就叫做绑定。
编译绑定(早期绑定)
在程序运行之前就进行了绑定,知道了方法调用来自于哪个具体的主体。这种方法是像c这样的程序化语言所采用的。编译绑定(后期绑定)
后期绑定是指在一些程序语言中出现通过一个句柄无法判断该句柄指向的具体的对象类型,而只能在程序运行的过程中,才能知道具体的类型,才能知道调用的方法的真实的对象主体。注意: 在Java中所有的方法几乎都是动态绑定的,只有声明为final的方法是在编译期就绑定的,因为final的方法是不能被继承重写的,所以一旦调用final的方法就能知道该方法调用对象类型,这样在编译器进行程序编译的时候就不需要对final的方法进行动态的绑定的编译,这样的对于该方法就更高效了。
二. 多态的实现
定义一个Shape(形状)的父类,定义了两个子类circle 和 Square 继承自Shape ,因为他们都是Shape的一种具体的形状。
代码如下:
父类Shape:
public class Shape {
protected void draw(){
System.out.println("Shape draw");
}
protected void mesure(){
System.out.println("Shape draw");
}
}
子类Circle
public class Circle extends Shape {
@Override
protected void draw() {
System.out.println("Circle draw");
}
@Override
protected void mesure() {
System.out.println("Circle mesure");
}
}
子类Square
public class Square extends Shape{
@Override
protected void draw() {
super.draw();
System.out.println("Square draw");
}
@Override
protected void mesure() {
super.mesure();
System.out.println("Square mesure");
}
}
执行代码:
Shape shape = new Circle();
shape.draw();
执行结果:
Circle draw
虽然是shape类型的句柄调用了draw方法,但是shape类型的句柄指向的对象类型是Circle,所以最终调用的方法draw是circle中的draw方法。
其中有两个重要的点:
父类型的句柄可以指向子类型对象
父类型的句柄调用的是该句柄最终运行的时候指向的对象的方法调用。