我们都知道Java的三大特性:封装、继承、多态。
Java中的向上转型及向下转型体现了Java中的继承性及多态性,所谓继承,不难理解,存在于子父类间,子类继承父类中不被私有化的属性和方法。而多态性,顾名思义,即是一件事物的多种不同体态的表现,Java中常理解为行为。
而多态的前提条件即是必须存在于父子类间,必须存在方法重写,方可体现多态性。下面给大家看下一段简单的代码语句。
父类Animal和其子类Dog、Cat
父类中的唯一方法sleep(),因为讨论的是向上转型及向下转型,所以与属性无关。
子类Dog中重写了父类的sleep()方法,以及独有的方法run()。
现在测试类中,我们实现多态向上转型:
从这里我们可以看出多态向上转型,即父类引用指向子类对象。这时候,animal可以调用的有继承父类的方法,也可以调用子类重写父类的方法。但是,无法调用子类中独有的方法。如果需要调用子类中独有的方法,这个时候,我们就需要多态向下转型:
(上诉书写方式取决于个人习惯,类似于基本数据类型的强制类型转换。)
这里两种方式都可以实现多态向下转型,方式一即是将animal的引用地址赋值为dog引用,这时候dog引用就可以调用子类中独有的方法,相当于一个子类对象。但是animal仍然无法直接调用子类中独有的方法。但是,需要注意的是,当我们使用多态向下转型的时候,指向的某个子类对象只能向下转型成某个子类。比如在这里,animal无法向下转型成Cat对象,这里会出现ClassCastException。到这里,我们就表现出了多态的向上转型及向下转型。
浅谈方法一:
这里有个地方需要稍微注意下,方式一的书写方式意为将堆中animal对象的引用地址赋值给对象dog,并没有创建(new)新的对象。我们可以验证一下。
可以看出,这两个引用变量输出的引用地址的哈希值完全一致,说明这两个引用变量指向的都是堆空间中同一块内存空间,也就是同一个对象。这里可以理解为,当我们使用了多态向上转型之后,也就是父类引用变量指向子类对象,我们创建的(new出来的)对象就是一个子类对象,只不过,这时候子类中独有的方法都被隐藏了,只能调用继承父类的方法和子类中重写父类的方法。而当我们使用了向下转型,子类中隐藏的独有的方法就可以被调用了。