上播和下播是Java的重要组成部分,它使我们能够使用简单的语法来构建复杂的程序,并给我们带来了很大的优势,例如多态或将不同的对象分组。Java允许将子类类型的对象视为任何超类类型的对象。这称为向上转换。向上转换是自动完成的,而向下转换必须由程序员手动完成,我将尽力解释为什么会这样。
向上转换和向下转换与将原语相互转换不一样,我相信当程序员开始学习转换对象时,这会引起很多混乱。
多态:默认情况下,java中的所有方法都是虚拟的。这意味着在继承中使用任何方法都可以覆盖,除非该方法声明为final或static。
您可以在下面的示例中getType();
根据对象(狗,宠物,警犬)的类型工作。
假设你有三只狗
狗-这是超级班。
宠物狗-宠物狗扩展了Dog。
警犬-警犬延伸宠物狗。
public class Dog{
public String getType () {
System.out.println("NormalDog");
return "NormalDog";
}
}
/**
* Pet Dog has an extra method dogName()
*/
public class PetDog extends Dog{
public String getType () {
System.out.println("PetDog");
return "PetDog";
}
public String dogName () {
System.out.println("I don't have Name !!");
return "NO Name";
}
}
/**
* Police Dog has an extra method secretId()
*/
public class PoliceDog extends PetDog{
public String secretId() {
System.out.println("ID");
return "ID";
}
public String getType () {
System.out.println("I am a Police Dog");
return "Police Dog";
}
}
多态:默认情况下,java中的所有方法都是虚拟的。这意味着在继承中使用任何方法时都可以覆盖它,除非该方法声明为final或static。(解释属于虚拟表概念)
虚拟表/调度表:对象的调度表将包含该对象的动态绑定方法的地址。通过从对象的调度表中获取方法的地址来执行方法调用。属于同一类的所有对象的分发表都是相同的,因此通常在它们之间共享。
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
版画 Normal Dog
obj2.getType();
版画 Pet Dog
obj3.getType();
版画 Police Dog
向下转换需要由程序员手动完成
当您尝试调用层次结构中的父类但又引用了该secretID();
方法的方法时obj3
,由于无法访问方法,将引发错误。为了调用该方法,您需要将该obj3手动向下转换为PoliceDog object
Dog
obj3
secretId()
PoliceDog
( (PoliceDog)obj3).secretID();
哪个打印 ID
以类似的方式调用类中的dogName();
方法,PetDog
您需要向下转换obj2
,PetDog
因为obj2被引用Dog
并且无权访问dogName();
方法
( (PetDog)obj2).dogName();
为什么会这样,向上转换是自动的,但是向下转换必须是手动的?好吧,您知道,向上转换永远不会失败。但是,如果你有一组不同的狗,并希望他们都垂头丧气到它们的类型,然后有机会的话,其中一些狗实际上是不同类型的,即,PetDog
,PoliceDog
,和过程失败,抛出ClassCastException
。
这就是如果您已将对象引用到超类类型时,需要手动向下转换对象的原因。
注意:这里通过引用意味着您在向下转换时不会更改对象的内存地址,它仍然保持不变,在这种情况下,您只是将它们分组为特定类型 Dog
Dog
是一个Animal
。在大多数情况下,除非您想使用某种重载的方法,否则不需要进行向上转换。和callme
中都存在。仅存在于中,您对其进行了强制转换以使其起作用。Animal
Dog
callme2
Dog
a
Dog