`
chen592969029
  • 浏览: 108537 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Java多态

    博客分类:
  • Java
阅读更多
先来看一个例子程序:DuoTaiTest.java
class Animal {
	void breathe() {
		System.out.println("animal breathe");
	}
	final static void live(Animal an) {
		an.breathe();
	}
}

class Fish extends Animal {
	void breathe() {
		System.out.println("fish bubble");
	}
}

class Cat extends Animal {
        void breathe() {
                System.out.println("cat breathe");
        }
}

public class DuoTaiTest {
	public static void main(String[] args) {
		Fish fish = new Fish();
                Cat cat = new Cat();
		Animal.live(fish);
                Animal.live(cat);
	}
}

Cat和Fish都继承于Animal,但都有自己的呼吸方式,因此覆盖了Animal类的breathe方法。但是并不用在Animal类中单独为Cat编写一个live方法。因为Animal类中的live方法就像是一个万能接口,当传递过来的Fish类的对象,它就会调用Fish类的breathe方法,当传递过来的是Cat类的对象,它就会调用Cat类的breathe方法。这就是面向对象的多态。

多态性是和继承密切相关的,他的含义就在于同一操作对不同对象可以呈现不同的行为。这些不同的对象必须是一组各具个性却同属于一个继承关系的不同个体。如Animal类中的Fish和Cat,他们有着不同的呼吸方式,但都通过覆盖Animal类的breathe方法来描述这一行为。此时,当执行Animal类的live方法时,将根据传递的具体对象的引用来决定调用相应的呼吸方法。显然这种可以根据传递不同对象的引用来调用不同对象的方法的机制,为实现面向对象编程赋予了更大的灵活性。

到这里,读者有没有想一下,在Animal类的live方法中接受一个Animal类的引用作为参数时,编译器是怎么知道这个Animal类的引用时指向Cat类而不是Fish类的呢?这种指向是发生在程序运行的那个阶段的呢?

为了深入理解内部的运行原理,首先看看什么是绑定机制。通常把对方法的调用连到方法本身的过程称为绑定。当绑定发生在程序运行之前时,称为前绑定。而在程序运行的时候根据对象的类型来决定绑定到哪个方法的机制称为后绑定,也称为动态绑定或者运行时绑定。对于上面的例子程序来说,在运行程序之前我们是无法决定live方法中的形参该指向哪一个对象的,因为这时候对象还没有产生,堆内存中并没有分配任何空间。因此,这是的编译器是不知道该指向哪一个对象类型的,只有在程序运行的时候,内存中有了实际存在的对象实体,才能在方法调用时判断出对象类型,进而调用正确的方法。可见,后绑定机制才是多态性真正的本质所在。

在多态性问题上一直有两个容易混淆的概念,这两个概念就是重载(overload)和覆盖(override)。重载是指在一个类里面允许存在多个同名方法的机制,这些方法必须保证拥有不同的参数列表,这种不同表现在参数个数,参数类型。而覆盖则是在子类中重新定义父类中的非私有方法,这种机制发生在继承关系中。

重载的实现其实是在程序编译阶段就被确定下来的事情,在编译时,编译器会根据方法不同德参数表决定具体讲调用哪个被重载的方法。首先,编译器将这些同名的方法的名称重新命名。由于这个过程是在编译阶段实现的,是静态的,因此这种绑定就是前绑定。它的好处就是整个绑定的过程是在编译阶段完成,因此程序执行效率很高。

重载机制好像有多态性的表现,但是重载绝对不是多态,他只是一种语言特性,不属于面向对象编程,因此与多态无关,与面向对象也无关。

真正和多态性有关的是覆盖机制。只有当子类重新定义了父类的同名方法后,父类的对象引用才可以格局赋给他的不同子类对象的引用,带太调用属于子类的该方法,从而使得方法的嗲用和方法本身只能在程序运行期间被动态绑定。因此,如果它不是后绑定,它就不是多态。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics