[英]Upcasting/Downcasting in Java
我试图了解 Java 中的向上转换和向下转换,我对以下情况感到困惑(关于我的代码,如下所示):
首先 - 为什么当我包含行myAnimal.bark();
,
第二 - (假设我注释掉myAnimal.bark();
)为什么调用 myAnimal.move myAnimal.move()
打印"moveDog"
而不是"moveAnimal"
? myAnimal
是否仅限于Animal
class 的方法,因为我们已将其类型声明为Animal
,即使我们将其设置为Dog
类型?
非常感谢任何帮助:这是代码:
public class Animal {
public void move() {
System.out.println("moveAnimal");
}
public static void main(String[] args) {
Dog myDog = new Dog();
Animal myAnimal = myDog;
myAnimal.move();
//myAnimal.bark();
}
}
class Dog extends Animal {
@Override
public void move() {
System.out.println("moveDog");
}
public void bark() {
System.out.println("bark");
}
}
这里有两个重要的概念相互竞争。
第一个概念是static typing ,这意味着 Java 编译器会在编译时检查您的表达式、变量和方法的类型,然后才能运行代码。 在这种情况下,变量myAnimal
的类型是Animal
,而Animal
类型没有方法bark()
,所以myAnimal.bark()
是一个类型错误。
第二个概念是动态分派,即在运行时根据object的类型来选择方法实现。 由于myAnimal
持有对 class Dog
的 object 的引用,因此对move()
方法的调用会调用Dog
class 中提供的该方法的实现。
使用此行的隐式向上转换:
Animal myAnimal = myDog;
您没有做任何事情来更改底层实例myDog
。 您正在做的是将其分配给 inheritance 树中更高一级类型的变量。 实际上,这将哪些方法限制为只能调用Animal
中定义的方法,但不会改变这些方法的解析方式。
因为您已将可用方法限制为仅在父 class Animal
上定义的方法,所以编译器无法解析Dog#bark()
,因为它是Dog
的方法,并且变量myAnimal
被定义为没有#bark
的Animal
类型#bark
法。
#move()
是Animal
和Dog
的方法,因此它解析,但它解析为Dog
上定义的方法,因为myAnimal
仍然引用Dog
的实例,尽管被向上转换。
在这里,您将 myAnimal 声明为 Animal 并且每只动物都不能吠叫。 即 myAnimal 在这里指的是动物。
动物 myAnimal = myDog;
但可以肯定的是,Dog 是一种可以吠叫的动物,因此您需要通过让 JVM 知道它的类型是 Dog 而不是 Just Animal 来明确地投射您的 myAnimal。
所以如果你改变 //myAnimal.bark(); 低于它会工作!
((狗) myAnimal).bark();
在这里,我们将 myAnimal 从 Animal 转换为 Dog。 因此 bark() 方法是允许的,它不会产生任何编译问题。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.