在面向对象的程序设计语言中,多态是继数据抽象(encapsulation)和继承(inherit)之后的第三种基本特征。
- 多态
- 多态的优点和缺陷
- 构造器与多态
- 协变返回类型
- 向上转型与向下转型
- 其他
多态
一个典型的多态,就是B、C 继承A ,并覆盖了其中的方法foo,有一段代码包含类型A,把B和C的引用可以传递过去,并且用A调用一个方法(A.foo),由于多态性,就会找到正确的B或C的相应的方法(foo)。
其中牵涉到覆盖、继承、向上转型。
带来的好处很多,最明显是,提高代码复用的能力。有的地方,类型只要写A的类型,就可以直接用,再扩展出D、E继承A,也可以继续使用这段代码。一个函数或者方法,表现出不同的效果,即是多态性。
看代码
import java.util.*;
class Shape {
void draw(){
}
}
class Circle extends Shape {
@Override
void draw(){
System.out.println("Circle.draw()");
}
}
class Triangle extends Shape {
@Override
void draw(){
System.out.println("Triangle.draw()");
}
}
public class HelloWorld {
public static void poly(Shape s){
s.draw();
}
public static void main(String[] args){
poly(new Triangle());
poly(new Circle());
}
}
s虽然是Shape类型,但是由于多态性,都能找到对应的方法,又叫后期绑定。
多态的优点和缺陷
优点:
扩展性,比如增加一个类型
Class Square extends Shape {
@Override
void draw(){
System.out.println("Squre.draw()");
}
}
//.....
poly(new Square());
关于poly方法可以不变。
缺点:
成员变量是不可以多态的,比如poly中使用shape的一个成员变量,那就不会去多态绑定。
静态方法不可以多态,静态方法是类方法,不属于某个对象。
构造器不可以多态,构造器本身是static。
构造器与多态
构造器本身不可以多态,构造器内部是可以多态的。
但是这样是不安全的,构造器内部调用成员方法,只有final的成员方法,是安全的,因为final的方法不不可以覆盖,不会发生多态的情况。
另外构造器的加载顺序,父类成员初始化、父类构造器、子类成员初始化、子类构造器。
协变返回类型
JAVA 1.5中提出的,关于覆盖。
父类中,
Type1 foo(int i){
}
子类中
Type2 foo(int i)『
}
如果Type2是Type1的导出类,这样也算覆盖。
向上转型与向下转型
class A {
void foo1(){}
}
class B extends A{
void foo2(){}
public static void main(String[] args){
A ob = new B();// 向上转型
// ob.foo2(); 会报错
((B)ob).foo2(); //向下转型
}
}
其他
暂无