多态

  多态是指当系统A访问系统B的服务时,系统B可以通过多种实现方式来提供服务,而这一些对系统A是透明的。

  在运行时,如果Shaver对象中的power变量引用AcPower对象,Java虚拟机就会调用AcPower()方法,否则,如果shaver对象中的power变量引用Battery对象,Java虚拟机就会调用Battery对象的providePower()方法。Java虚拟机的这种运作机制被称为动态绑定。

 1 class Base{
 2   String var="Base's Variable";
 3   void method(){System.out.println("call Base's method"); }
 4 }
 5 
 6 public class Sub extends Base{
 7   String var="Sub's variable";  //隐藏父类的var变量
 8   void method(){System.out.println("call Sub's method");}  //覆盖父类的method()方法
 9 
10   void test(){
11     String var="Local variable";  //局部变量
12 
13     System.out.println("var is "+var);  //打印method()方法的局部变量
14     System.out.println("this.var is "+ this.var);  //打印Sub实例的实例变量
15     System.out.println("super.var is "+ super.var); //打印在Base类中定义的实例变量
16 
17     method();  //调用Sub实例的method()方法
18     this.method();  //调用Sub实例的method()方法
19     super.method();  //调用在Base类中定义的method()方法
20   }
21 
22   public static void main(String args[]){
23     Sub sub=new Sub();
24     sub.test();
25   }
26 }

  (1)对于一个引用类型的变量,Java编译器按照它声明的类型来处理。例如在以下代码中,编译器认为who是Base类型的引用变量,而Base不存在subVar成员变量和subMethod()方法,所以编译出错。

1 Base who = new Sub(); //who是Base类型
2 who.subVar = "123";        //编译出错,提示在Base类中没有subVar属性
3 who.subMethod(); //编译出错,提示在Base类中没有subMethod()方法  

  如果要访问sub类的成员,必须进行强制类型的转换。

1 Base who = new Sub();
2 ((Sub)who).subVar = "123" //编译成功
3 ((Sub)who).subMethod();//编译成功

 

  Java编译器允许在具有直接或间接继承关系的类之间进行类型转换,对于向上转型,不必使用强制类型转换,因为子类的对象肯定也可看做父类的对象。对于向下转型,必须进行强制类型转换。

  (2)对于一个引用类型的变量,运行时Java虚拟机按照它实际引用的对象来处理。以下代码虽然编译可以通过,但运行时会抛出异常。如下:

 1 Base who = new Base(); //who引用Base类的实例

2 Sub s = (Sub)who; //运行时抛出ClassCastException 

  在运行时,子类的对象可以转换为父类类型,而父类的对象实际上无法转换为子类类型。因为子类拥有的成员父类不一定有。

     (3)在运行环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则。

  ①实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时有Java虚拟机动态决定的。

  ②静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定。

  ③成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,属于静态绑定。

  例如,对于以下这段代码:

1 Base who = new sub(); //who被声明为Base类型,引用Sub实例
2 System.out.println("who.var ="+who.var );  //打印Base类的var变量
3 System.out.println("who.staticVar="+who.ststicVar);//打印Base类的staticVar变量
4 who.method();         //打印Sub实例的method()方法
5 who.staticMethod();             //打印Base类的staticMethod()方法

运行时将会输出如下结果

who.var =Base's Variable
who.staticVar=Base's staticVar
call Sub's method
call Base's staticMethod

 

posted @ 2014-08-17 10:24  Phil Li  阅读(191)  评论(0)    收藏  举报