简体   繁体   English

Java中的对象类型混淆

[英]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?经过搜索,我找到了Java polymorphism 中的 Confusion的解释,它说:“尽管 x 明确声明为类型 A,但它被实例化为类 B 的对象,因此我将运行 doIt() 方法的版本,即在 B 类中定义。”但是在我使用 A 类构造函数实例化对象 a 之后,它仍然打印“我是 B”,所以有人可以为我解释一下吗?

    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 . a1a2都指定了引用b ,它引用了B类的对象。 Therefore class B 's implementation of printDescription was executed for both, and you got the "I'm B" output for both. 因此, printDescription两个类都执行了B类的printDescription的实现,并且得到了这两个类的“ I'm B”输出。

a1=b;

b is a B , and you assign it to a1 . bB ,您将其分配给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 . 由于您为a1分配了B ,因此它是一个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 在代码a1中,a2和b是指向B实例的引用变量。首先创建一个对象A,如下所示:

A a1 = new A();

but later you asign it to "b" as 但后来您将其指定为“ b”

a1 = b

Thats why it is executing method from class B not from class A 这就是为什么它从B类而不是从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]. 您的前三个喜欢设置三个参考变量[b,a1和a2]。 They also set up two objects [new B() and new A()]. 他们还设置了两个对象[new B()和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. 它将b指向新的B()对象,将a1指向新的A()对象,然后将a2指向b指向的对象。

Then, your line "a1 = b" points the a1 reference variable the object pointed at by b (which is the same B() object. 然后,您的“ a1 = b”行将a1引用变量指向b指向的对象(与B()对象相同)。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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