Java 三大特质之多态

来源:互联网 发布:中欧基金 知乎 编辑:程序博客网 时间:2024/06/06 20:59

我觉得一个高水平的老师可以知识讲解的简单明了,而一个低水平的老师则会把知识更加复杂化,讲解的晦涩难懂。原因在于其没有深刻的理解,抓住事物的本质特征。其讲解的复杂度也就负相关于了学生的理解接收程度。因此本博客写作力求深刻理解事物本质,然后用简洁明了的语言将其阐述清楚。

多态一个引用变量的多种状态。具体一点就是,程序定义的父类引用变量所指向的子类对象在编程时是不确定的,而是在程序运行期间确定的。怎么理解?看下面代码,现在讲太多道理太空洞。

public class Test12 {public static void main(String[] args) {// TODO Auto-generated method stubAnimal1 a= new Cat1();a.speak();a =new Dog1();a.speak();}}class Animal1{String name;int age;public void speak(){System.out.println("我是动物,不知道怎么叫!!");}}class Cat1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小猫,喵喵喵!");}}class Dog1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小狗,汪汪汪!");}}


可以看到,同一个引用变量 a  ,在不同的时刻既可以指向new Cat(),又可以指向new Dog()。这就是“多态”。

慢着,以前我们在创建一个类的对象时,是这样的Cat cat=new Cat(),但是却是这样Animal a=new Cat();。这样做可以吗?

答案是肯定的。由于Cat可以自动“向上转型”为Animal,所以 a 是可以指向Cat 的实例对象的。向上转型”的概念是初次接触,本来应该加以介绍,限于篇幅所限,暂且按住不表。留待下文分解。

继续说“多态”,看下面Code

public class Test12 {public static void main(String[] args) {// TODO Auto-generated method stubAnimal1 a= new Cat1();a.speak();a.eat();a =new Dog1();a.speak();}}class Animal1{String name;int age;public void speak(){System.out.println("我是动物,不知道怎么叫!!");}}class Cat1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小猫,喵喵喵!");}public void eat(){System.out.println("我是小猫,我爱吃鱼!");}}class Dog1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小狗,汪汪汪!");}}

在上一个code的基础上,为Cat增加的eat()方法,并且用父类引用a来调用。可以吗?我们发现编译都编不过去。在a.eat() 处报错。eclipse 提示“The method eat() is undefined for the type Animal1”

看看,提示的很清楚!说明什么,说明现在父类引用a 的类型是animal ,不是Cat,因此它能够调用的只能是animal中存在的方法,如果animal中不存在,则无法调用。

再看code

public class Test12 {public static void main(String[] args) {// TODO Auto-generated method stubAnimal1 a= new Cat1();a.speak();a.eat();a =new Dog1();a.speak();}}class Animal1{String name;int age;public void speak(){System.out.println("我是动物,不知道怎么叫!!");}public void eat(){System.out.println("我是动物,我就要吃!");}}class Cat1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小猫,喵喵喵!");}}class Dog1 extends Animal1{//Overridingpublic void speak(){System.out.println("我是小狗,汪汪汪!");}}

在上面的code中,在animal中写了eat()方法,然后在父类引用a 处调用eat()方法,完全正确。

总结一下,在实现多态以后,父类引用的类型是父类的类型,而不是子类的类型;父类引用可以调用的方法是被子类继承或者重写的方法。




0 0