在Java中,引用子类引用的超类变量的实际类是什么?

在Java中,引用子类引用的超类变量的实际类是什么?,java,inheritance,reference,Java,Inheritance,Reference,我对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(St

我对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()告诉我动物的类是狗。但是test.get_dog(动物)不会运行,说get_name()只接受一个dog类而不是动物类。那么,动物的职业到底是什么呢?

试试这个:

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

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

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


查看:Java中的多态性和类型转换这里的混淆是静态类型和动态类型。在编译时,
a_animal
变量被编译器称为
animal
。尝试将其用作
失败,因为编译器知道并非所有动物实例都是狗(即动物不是狗,也不是狗的子类)


在运行时,
a_animal
将引用狗,该调用将起作用。要了解这是如何进行的,请将
test.get\u dog(a\u animal)
更改为
test.get\u dog((dog)a\u animal)
-此
(dog)
是一个强制转换,告诉编译器将
a\u animal
视为狗类型。

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


在运行时,
a_animal
将引用狗,该调用将起作用。要查看结果,请将
test.get\u dog(a\u animal)
更改为
test.get\u dog((dog)a\u animal)
-此
(dog)
是一个强制转换,它告诉编译器将
a\u animal
视为狗类型。

根据代码,您应该将动物对象传递给get\u dog方法,而不是dog对象。你所尝试的就是向上投射。父类的引用变量引用子类的对象,如下所示

 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();//
    }
}
下面是结果

解释

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


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

根据您的代码,您应该将动物对象传递给get_dog方法,而不是dog对象。你所尝试的就是向上投射。父类的引用变量引用子类的对象,如下所示

 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();//
    }
}
下面是结果

解释

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


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

声明的类型是
Animal
,但实际类型是
Dog
。声明的类型规则在Java中,除非您编写显式类型转换,如
test.get_Dog((Dog)a_Animal)
你可以参考下面的解释和我给出的答案@Wayne Yiquan声明的类型是
Animal
,但实际的类型是
Dog
。声明的类型规则是Java的,除非你编写一个显式类型转换,如
测试中。get_Dog((Dog)a_Animal)你可以参考我在@Wayne Yiquan下面给出的解释和答案,而这段代码可能会回答这个问题,提供关于如何和/或为什么解决这个问题的额外上下文将提高答案的长期价值。虽然这段代码可能会回答这个问题,提供关于如何和/或为什么解决问题的附加上下文将提高答案的长期价值。