2

我写了这段代码:

class A {
    int a;

    void method() {
        System.out.println("Overridden method of Class A called!");
    }

    void method2() {
        System.out.println("Normal Method of Class A called!");
    }
}

class B extends A {
    int b;

    void method() {
        System.out.println("Overridden method of Class B called!");
    }

    void method1() {
        System.out.println("Normal Method of Class B called!");
    }
}

class C {
    public static void main(String[] args) {
        A a1 = new A();
        B b1 = new B();
        a1 = b1; // ***Line 1***
        System.out.println("After referencing!");
        a1.method();
        a1.method2();

        A a2 = new B(); // ***Line 2***
        a2.method();
        a2.method2();
    }
}

第 1 行和第 2 行在上面的代码中用注释标记

现在,我对Line 1的物理意义有了一些了解,但是Line 2到底是什么意思呢?内存是如何分配给类型 A 的对象“ a2 ”的?这种对象的性质和行为是什么,它与普通实例化有何不同?第 1 行第 2 行是否传达相同的含义?如果是这样,怎么做?如果不是,它们有何不同,因为显然它们提供相同的输出。

4

5 回答 5

1

这两行都类似于以下内容

Object obj = new SomeClass();

但是在 Line1A中创建了一个额外的类型对象。

所以随着

    A a1 = new A();  // a new object
    B b1 = new B();  // another object
    a1 = b1; // make a1 point to the b1 and lose the reference to original `A` type object

    A a2 = new B(); // create a new `B` object and assign it to reference of `A` type.

所以本质上是相同的(除了 line1 中的额外对象)

这两行在内部使用polymorphism.

于 2013-06-20T15:37:10.360 回答
1

他们是一样的。在 Java 中,所有对象引用都保持相同数量的内存。所以同一个 Object 引用的内存空间可以指向任何 Java Object。编译器强制你只分配一个引用A来指向一个扩展类的对象A。在上述两种情况下,您都有一个指向Aclass 实例的类型的引用(C 中的指针) B

于 2013-06-20T15:23:07.213 回答
1

a2 是[A 类型] 的引用类型,它引用B 类型的对象。就是这样,仅此而已。

是的 Line1 和 Line 2 是一样的。只是做同一件事的不同方式。

于 2013-06-20T15:24:53.480 回答
1

两者都是等价的,但唯一的区别是,在第一个中,您不必要地创建了一个 of A( new A();),而您只是将其丢弃。

A a1 = new A(); // new A() should not be done here
B b1 = new B();
a1 = b1; // ***Line 1***

最好按以下方式进行 -

//A a1 = new A(); // new A() should not be done here
B b1 = new B();
A a1 = b1; // ***Line 1***

它们是相似的,因为在这两种情况下,您都在实例化B( new B();) 的一个对象,并创建一个类型变量A来引用该实例。

于 2013-06-20T15:25:20.160 回答
1

始终尝试编写接口而不是具体实现,除非在您认为合适的情况下(例如 Swing 中的类,其中 UI 组件具有具体实现,但您可以覆盖它以获得更好的 UI 或您选择的 UI)。

现在考虑您的情况,如果我只是为不同的行为(即不同的方法实现)进行这种继承,我会更喜欢由 A 类和 B 类实现的接口“I”。这就是它开始变得更有意义的地方。

上面解释了设计的角度。

现在从编码的角度来看。超类总是引用子类对象。但是当你访问一个方法时,它是被调用的对象的方法,而不是引用类型的方法。

A a1 = new A();//Object of A in heap which is referred by reference of A
        B b1 = new B();//Object of B in heap which is referred by reference of B
        a1 = b1; // ***Line 1*** Here super type(a1) is referring to subtype b1. So actual object is that of class B.
        System.out.println("After referencing!");
        a1.method();//method from actual object is called ie b1
        a1.method2();//same

        A a2 = new B(); // ***Line 2*** again object created in heap is of type B but its referred by super type A
        a2.method();//and hence,method called is from B class not from class A
        a2.method2();
于 2013-06-20T15:53:15.057 回答