Java多态(Polymorphism)的实现机制(下)--Java篇

  
既然多态是面向对象的老三异常精神特征有(其它少只是数据抽象和延续),那么C++为什么不以方调用的默认方式设置也动态绑定,而只要透过主要字
virtual进行标记为?Bruce Eckel在《Thinking in
C++》中涉及,这是由历史由来造成的,C++是自C发展要来的,而C程序员最为关切的是性问题,由于动态绑定比静态绑定多几乎长达指令,性能有回落,
如果将动态绑定设定为默认方法调用方式,那么多C程序员可能未见面经受,因此,C++就拿动态绑定定位成可卜的,并且作出保证:If
you don’t use it, you don’t pay for it(Stroustrup)。
   
但是,Java作一个新的意面向对象的语言,并无存在向下兼容的问题,同时,Java的设计者为道多态作为面向面向对象的中心,面向对象语言应该提供放置的支持,因此,Java将动态绑定作为艺术调用的默认方式。
    下面,我们就算详细地来询问一下Java是哪些也多态提供支撑之。
与C++一样,Java中吗发生一个存放实例方法地址之数据结构,在C++中,我们管其称为VTable,而以java中方法表(Method
Table),但是双方发生好多平的处在:
     1、它们的作用是一律之,同样用来拉实现方式的动态绑定。
     2、同样是相近级别的数据结构,一个像样的持有目标共享一个方法表。
     3、都是由此偏移量在该数据结构中寻觅某一个方。
    
4、同样保证所有派生类中继承给基类的道在点子表中的偏移量跟该方法以基类方法表中的偏移量保持一致。
     5、方法发明中还只能存放多态方法(Java中之实例方法,C++中是vitual方法)。

    
但是究竟,C++是一模一样山头编译型的言语,而Java更加偏向于解析型的,因此上述数据结构的变与维护是大相径庭的,表现在:
    
1、C++中VTable和vptr是以编译阶段由编译器自动生成的,也就是说,在C++程序载入内存以前,在.obj(.o)文件中早已起这些构造的信
息;Java中之方法发明是由JVM生成的,因此,使用javac命令编译后生成的.class文件被连不曾办法发明的音讯。只有等JVM把.class文件
载入到内存中时,才见面吧该.class文件动态变化一个同之干的方法表,放置在JVM的方法区中。
   
2、C++中某个方法在VTable的索引号是在编译阶段都显著知道之,并不需要在运转过程被动态获知;Java中之法子初始时都不过是一个标志,并无是
一个明确的地点,只有等及该方式给第一涂鸦调整用时,才见面被分析成一个方法表中的偏移量,也就是说,只有当此时节,实例方法才明白掌握好在方发表着之舞狮
量了,在这之前必须经历一个解析的进程。

   
此外,Java中不支持多更继承,也即无见面如C++那样在这泥潭中纠缠不清了,但Java也引入了新的定义,那便是接口,Interface。使用Interface调用一个实例方法及用一个Class来调用的进程是未均等的:

public class  Zoo
{
 public static void main(String[] args)
 {
   Pet p1 = new Dog();
   Pet p2 = new Dog();
   p1.say(); //首先解析一涂鸦,得到偏移量,调用方法
   p2.say(); //不用解析,直接使用上次的落的偏移量,调用

  Cute c1 = new Dog();  
  Cute c2 = new Dog();
  c1.cute(); 
//这里用接口来调用实例方法,首先同样会分析一破,得到偏移量,调用相应措施
  c2.cute(); //这里虽然上次就解析了了,但是要得重新与上次同等重复分析一不良,得到偏移量,调用
 }
}

interface Cute
{
 public void cute();
}

class Pet
{
  public void say(){ System.out.println(“Pet say”);  }
}

class Dog extends Pet implements Cute
{
     public void cute(){ System.out.println(“Dog cute”); }
     public void say(){ System.out.println(“Dog say”);  }
}

   
为什么会出诸如此类的区别为?这是盖实现与一个接口的类似并无能够管还是从同一个超类继承的,而且此超类也一样实现同的接口。因此,该接口声明的主意并无可知还保证处于方法表中的跟一个位置及。如,可以定义下面的类:

class Cat  implements Cute
{
     public void cute(){ System.out.println(“Cat cute”); }
}

   
那么,Dog跟Cat同样都实现了接口Cute,因此还能用Cute接口进行调用,但是方法cute在Dog方法表中的职并无能够确保该措施以Cat方
法表中的职务是一样的。因此,对于接口调用方法,我们只好每次都还分析一道,获得精确之偏移量,再开展调用了。这也促成了利用接口调用方法的效率要于要
用类调用实例方法没有。当然,这单是对立而言,JVM在落实上会见予以优化,我们无克说盖接口效率低就不行使了,相反由于当面向对象作用被接口的强有力作
用,java是倡导使用接口的,这无异于点我们是亟需注意的。
   
还有某些,虽然java不支持类的文山会海继承,但是是可以兑现多个接口的,那么,在Java中见面无会见如像C++的层层继承那样进行必要的更换为?这个问题,
我们惟有需要想转手两头调用的实际经过,就能知道,Java的接口方法每次调用前都是得分析的,在此处才见面赢得实在的偏移量,这同C++中编译期间取得偏移
量是匪一样,因此,在Java中凡无待开展所谓的换的。
转http://hi.baidu.com/daping\_zhang/blog/item/e0360d333f33fbf81a4cffaa.html/cmtid/928ebd3e145bb4f2828b13a9\#928ebd3e145bb4f2828b13a9
   

相关文章