-
向上转型
例如创建子类对象时引用指向父类对象时,我们把这种情况叫做向上转型
比如 多边形 x=new 正方形()
多边形 y=new 菱形()
实现接口也是多态的一种表现 -
静态绑定与动态绑定
当我们执行以下代码,虽然大家都知道我们创建的是子类对象,只是把引用指向了父类对象,但是编译器是怎么知道我们想要调哪个子类呢?
这就涉及到了方法的动态绑定,将一个方法调用同一个方法主体关联起来被称作绑定。编译时期进行绑定叫前期绑定或静态绑定,在编译的时候,编译器只有一个Shape引用,它应该无法知道调用哪个方法。
这样解决的办法就是后期绑定,也叫动态绑定或运行时绑定。它根据运行时对象的类型进行绑定,但要想实现后期绑定必须实现这种机制,才能调用正确的方法。
所以在java语言中设定除了静态方法(构造器也属于静态方法)和final方法(private方法也属于final方法),其他的方法都是后期绑定。所以说java中是通过动态绑定来实现运行时多态的(重写)
动态绑定的过程:
虚拟机提取对象实际类型的方法表
虚拟机搜索方法签名
调用方法通过静态绑定来实现编译时多态(重载)
import static java.lang.System.out;
class Shape {
public void draw(){ }
public void erase(){ }
}
class Circle extends Shape{
public void draw(){ out.println("Circle.draw()");}
public void erase(){ out.println("Circle.erase()");}
}
class Square extends Shape{
public void draw(){ out.println("Square.draw()");}
public void erase(){ out.println("Square.erase()");}
}
class Shapes {
public static void main(String[] args) {
Shape shape = new Circle();
shape.draw();
shape.erase();
}
}
Output:
Circle.draw()
Circle.erase()
-
向下转型
在java语言中向下转型只是加一个括号进行类型转化,如果不是我们所想要转化的那种类型,会返回一个ClassCastException异常。 -
多态的缺陷
只有非private方法才能被覆盖,所以对于父类中的private方法,子类最好采用不同的名字。
父类的属性最好也是private的,直接访问某个属性,这个访问会在编译期进行解析,当子类和父类具有相同的属性名字时子类对象引用指向父类调用的属性是父类的属性名字而不是子类的。 -
多态的好处
多态不仅能够改善代码的组织结构和可读性以及消除代码之间的耦合 ,还能够创建可扩展的程序。