【问题标题】:In Java, what is the actual class for a superclass variable that is referencing a subclass reference?在 Java 中,引用子类引用的超类变量的实际类是什么?
【发布时间】:2019-06-26 02:54:43
【问题描述】:

我还是 Java 新手,我对 Java 如何处理引用子类引用的超类变量感到有些困惑。 我有两个班级:

public class Animal{
}
public class Dog extends Animal{
}

然后我创建了一个 Run 类,如下所示:

public class Run{
    public void get_dog (Dog a){
        System.out.println("got a dog");
    }
    public static void main(String[] args) {
        Animal a_animal = new Dog(); //Create a Animal variable with Dog class
        Run test = new Run();
        System.out.println(a_animal.getClass().getSimpleName());
        test.get_dog(a_animal); //This will not run
    }
}

getClass().getSimpleName() 告诉我 a_animal 的类是 Dog。但是 test.get_dog(a_animal) 不会运行,说 get_name() 只会采用 Dog 类而不是 Animal 类。那么 a_animal 的类到底是什么?

【问题讨论】:

  • 声明的类型Animal,但实际类型Dog
  • declared 类型规则在 Java 中,除非您编写显式 type cast,如 test.get_dog((Dog)a_animal);
  • 你可以参考我在下面@Wayne Yiquan 给出的解释和答案

标签: java inheritance reference


【解决方案1】:

根据您的代码,您应该将 Animal 对象传递给 get_dog 方法,而不是 Dog 对象。您尝试过的方法称为 upcasting 。 Parent类的引用变量引用Child类的对象如下。

 Animal a_animal = new Dog();

我已经为你重写了一个代码来理解下面的概念

public class Animal {
    void run() {
        System.out.println("An animal is running");
    }
}


public class Dog extends Animal {
    void run() {
        System.out.println("Dog is running in 20kmph");
    }
}



public class Run{
    public static void main(String[] args) {
        Animal a_animal = new Dog(); //Creating a reference variable of Animal class by referring to Dog class (upcasting)
        a_animal.run();//
    }
}

下面是结果

说明

我们通过Parent类的引用变量调用run方法。由于它引用了子类对象并且子类方法覆盖了父类方法,因此子类方法在运行时被调用。

方法调用是由JVM而不是编译器决定的,称为运行时多态。

【讨论】:

    【解决方案2】:

    这里的混淆是静态类型与动态类型之一。在编译时,a_animal 变量被编译器称为Animal。尝试将其用作 Dog 失败,因为编译器知道并非所有 Animal 实例都是狗(即 Animal 不是 Dog,也不是 Dog 的子类)。

    在运行时,a_animal 将引用 Dog,并且该调用将起作用。要查看结果如何,请将 test.get_dog(a_animal) 更改为 test.get_dog((Dog) a_animal) - 此 (Dog) 是一个强制转换,它告诉编译器将 a_animal 视为 Dog 类型。

    【讨论】:

      【解决方案3】:

      试试这个:

       test.get_dog((Dog)a_animal); 
      

      get_dog() 方法需要一个 Dog 对象作为参数。由于您的 a_animal 首先初始化为 Animal 类,因此您需要将其显式类型转换为 Dog 对象,以便它知道您的 a_animalDog 对象。

      查看:Java 中的多态性和类型转换

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      猜你喜欢
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 2023-04-05
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多