繁体   English   中英

Java 中的上调/下调

[英]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被定义为没有#barkAnimal类型#bark法。

#move()AnimalDog的方法,因此它解析,但它解析为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM