在面向对象的程序设计语言中,多态是继数据抽象(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(); //向下转型 }}
其他
暂无