【问题标题】:Upcasting/Downcasting in JavaJava中的向上转换/向下转换
【发布时间】:2019-11-05 23:59:30
【问题描述】:

我试图理解 Java 中的向上转换和向下转换,但我对以下情况感到困惑(关于我的代码,如下所示):

首先-为什么当我包含myAnimal.bark();行时代码无法编译,

第二个-(假设我注释掉myAnimal.bark();)为什么调用myAnimal.move() 打印"moveDog" 而不是"moveAnimal"myAnimal 不是仅限于来自Animal 类的方法吗,因为我们已将其类型声明为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");
        }
    }


【问题讨论】:

  • Animal::bark 方法不存在所以无法调用。
  • myAnimal 不限于 Animal 类中的方法 - 这就是 OO 的全部意义所在。 子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型的实例方法作为超类中的实例方法会覆盖超类的方法。
  • 是的,那为什么要打印moveDog,而不是moveAnimal?

标签: java inheritance downcast upcasting


【解决方案1】:

在这一行带有隐式向上转换:

Animal myAnimal = myDog;

您没有做任何事情来更改底层实例myDog。您正在做的是将其分配给继承树中更高一级类型的变量。实际上,这将哪些方法限制为只能调用 Animal 中定义的方法,但不会改变这些方法的解析方式。

由于您已将可用的方法限制为仅在父类Animal 上定义的方法,因此编译器无法解析Dog#bark(),因为它是Dog 的方法,并且变量myAnimal 被定义为类型为Animal,没有#bark 方法。

#move()AnimalDog 的方法,所以它解析,但它解析为Dog 上定义的方法,因为myAnimal 仍然引用Dog 的实例,尽管被淘汰了。

【讨论】:

  • 英文通俗易懂的好答案
【解决方案2】:

这里有两个重要的概念相互竞争。

第一个概念是静态类型,这意味着 Java 编译器会检查您的表达式、变量和方法的类型在编译时,在代码得到一个跑的机会。在这种情况下,变量myAnimalAnimal类型,而Animal类型没有方法bark(),所以myAnimal.bark()是一个类型错误。

第二个概念是动态分派,意思是在运行时根据对象的类型来选择方法实现。由于myAnimal 持有对Dog 类对象的引用,因此对move() 方法的调用会调用Dog 类中提供的该方法的实现。

【讨论】:

    【解决方案3】:

    在这里,您将 myAnimal 声明为 Animal 并且每只动物都不能吠叫!即 myAnimal 在这里指的是 Animal。

    动物 myAnimal = myDog;

    但可以肯定的是,Dog 是一种可以吠叫的动物,因此您需要通过让 JVM 知道它的类型为 Dog 而不是 Just Animal 来显式地转换 myAnimal。

    所以如果你改变 //myAnimal.bark();到下面就可以了!

    ((狗) myAnimal).bark();

    在这里,我们将 myAnimal 从 Animal 转换为 Dog。因此 bark() 方法是允许的,它不会产生任何编译问题。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-03-16
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      相关资源
      最近更新 更多