No.19  

一直对Java的一些概念理解的不是很好,多态就是其中一个。把目前对多态的理解写下来,方便以后回忆和补充。

按我自己对多态的理解,多态,顾名思义就是多种形态,而所谓的多种形态,比如现在有B,C类都继承了A类,

A a1 = new B();

A a2 = new C();

虽然都是A类定义出来的,但他们有不同的构造方法,因此就有不同的形态。所以实现多态,首先要有继承。继承之后,子类的对象可以调用父类中所有的非私有的方法(即可以调用public和protected修饰的方法),但如果子类仅仅只继承了父类,而没有重写父类的某些方法的话,那直接使用父类就行了,何必去继承呢。而且在使用的时候也体现不出多态的性质了。所以实现多态的另一个条件是:重写。因为有了重写,才有了动态调用,这个在下面再详谈。另外,在网上有看到实现多态还要有重载,这个我就百思不得其解,按我自己的理解怎么都没办法把多态跟重载联系起来。

多态性是允许你将父对象设置成为一个或更多和他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。多态就意味着父类型的变量可以引用子类型的对象。Java提供的类中就有很多这样的情况,如String类型的equal()方法,括号中的参数类型为Object,因为所有的类都继承了Object,所以Object类是所有类的父类,我可以用equal(String)调用这个方法,这便是一个父类型变量引用子类型对象的例子。

考虑下面的例子

class Father{

  public void say(){

    System.out.println("I'm father");

  }

}

class Son extends Father{

  public void say(){

    System.out.println("I'm son");

  }

}

Father father = new Son();

在这里Son类重写了Father类的say()方法,这个时候若执行father.say()会输出什么?答案是I'm son,即调用了子类的方法。首先这里先涉及下两个术语:声明类型和实际类型。一个变量必须被声明为某种类型,这里的father的声明类型为Father。变量的实际类型是被变量引用的对象的实际类,这句话有点拗口,放在这里的意思就是father的实际类型是被father引用的对象的实际类,即Son。

father调用的到底是那个say()方法是由father的实际类型所决定的,这被称为动态绑定。

动态绑定的工作机制为:假设c1被c2继承,c2被c3继承,一直继承到cn,c1可以理解为Object类,这个时候声明一个Object类型的变量,并引用了cn对象,即

Object o = new cn(),如果对象o调用方法p,java虚拟机会在沿着继承链往上查找方法p,即从子类往父类查找(前提是父类和子类都有p方法,就是说p是一个被重写了的方法,而不是属于某个子类中的方法而已),并调用第一个查找到的方法p。

posted on 2013-11-12 23:56  No.19  阅读(208)  评论(0)    收藏  举报