简体   繁体   中英

Object type confusion in Java

public class Test {
    public static void main(String[] args){
        B b=new B();
        A a1=new A();
        A a2=b;               
        a1=b;
        a1.printDescription(); //which prints I'm B
        a2.printDescription(); //which also prints I'm B 
    }
}
class A{
    public void printDescription(){
        System.out.println("I'm A");
    }
}

class B extends A{
    public void printDescription(){
        System.out.println("I'm B");
    }
}

After searching,I find an explanation Confusion in Java polymorphism ,which said: "even though x is clearly declared as type A, it is instantiated as an object of class B, so I will run the version of the doIt() method that is defined in class B."But after I instantiated object a using class A constructor,it still prints "I'm B",so would anyone can explain this for me?

    B b=new B(); // b refers to an object of class B
    A a1=new A(); // a1 refers to an object of class A
    A a2=b; // a2 refers to an object of class B              
    a1=b; // now a1 refers to an object of class B

Both a1 and a2 were assigned the reference b , which refers to an object of class B . Therefore class B 's implementation of printDescription was executed for both, and you got the "I'm B" output for both.

a1=b;

b is a B , and you assign it to a1 . It does not matter what the type says at compile time. All that matters is what it actually is when you run it. Since you assign a1 a B , it is a B .

Going through line by line:

B b=new B();  //b is a B
A a1=new A(); //a1 is an A, b is a B
A a2=b;       //a1 is an A, b is a B, and a2 is the same B as b
a1=b;         //a1, a2 and b are all references to the same B value

It is because of late binding . You have method overriding here (derived class implements a method with the same name as base). This leads that the most-derived type method held on the variable reference and not the reference type, will be called, and this will be determined at runtime.

For example:

//This is an A-type reference, referencing to a A-type object
A a = new A();
B b = new B();

//The A-type reference, is now referencing to the B-type object.
//The old, A-type object held will be set for garbage collection.
A a = b;

//This will call the mostly derived type referenced method (which is B),
//which prints "I'm B"
a.printDescription();

In your code a1, a2 and b are your referance variable which are pointing to instance of B. you start with creating an object of A as

A a1 = new A();

but later you asign it to "b" as

a1 = b

Thats why it is executing method from class B not from class A

This diagram explains what's going. The top half shows your code, and the bottom half tries to picture it in memory.

Your first three like set up three reference variables [b, a1 and a2]. They also set up two objects [new B() and new A()]. It points b to the new B() object, it points a1 to the new A() object, and then it points a2 to the object pointed at by b.

Then, your line "a1 = b" points the a1 reference variable the object pointed at by b (which is the same B() object.

在此处输入图片说明

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