简体   繁体   中英

In Java, what is the actual class for a superclass variable that is referencing a subclass reference?

I am still new to Java, and I am a bit confused with how Java is treating a superclass variable that is referencing a subclass reference. I have two classes:

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

And then I created a Run class as below:

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
    }
}

The getClass().getSimpleName() tells me that a_animal's class is Dog. But the test.get_dog(a_animal) will not run, saying get_name() will only take a Dog class instead of a Animal class. So what exactly is the class for a_animal?

As per your code you should pass an Animal object to get_dog method and not a Dog object. What you have tried is called upcasting . A reference variable of Parent class refers to the object of Child class as below.

 Animal a_animal = new Dog();

在此处输入图片说明

I've re-written you a code to understand the concept as below

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();//
    }
}

Below is the result

在此处输入图片说明

Explanation

We are calling the run method by the reference variable of Parent class. Since it refers to the subclass object and subclass method overrides the Parent class method, the subclass method is invoked at runtime.

The method invocation is determined by the JVM and not the compiler, it is known as runtime polymorphism.

Try this:

 test.get_dog((Dog)a_animal); 

the get_dog() method is expecting a Dog object as the parameter. Since your a_animal is first initialized as a Animal class, you need to explicitly typecast it as a Dog object, so that it knows that your a_animal is a Dog object.

Check out: Polymorphism and Type casting in Java

The confusion here is one of static typing versus dynamic typing. At compile-time, the a_animal variable is known to the compiler as an Animal . Trying to use it as a Dog fails because the compiler knows that not all Animal instances are dogs (ie Animal is not Dog, and is not a subclass of Dog).

At runtime, the a_animal will reference a Dog, and that call would work. To see how this plays out, change test.get_dog(a_animal) to test.get_dog((Dog) a_animal) - this (Dog) is a cast that tells the compiler to treat a_animal as a Dog type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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