2013-06-20 19 views
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號線在上面的代碼中打上了意見

現在,我對的1號線的物理意義的一些想法,但究竟是什麼第2行是什麼意思? 內存是如何分配給對象'a2'的A型?這個對象的本質和行爲是什麼?它與正常實例有什麼不同?是否線1線2表達相同的意思?如果是這樣,怎麼樣?如果不是,他們有什麼不同,因爲他們顯然是相同的產出。

+4

首先要注意的是術語。 'a2'不是一個對象,它是一個變量。它的價值是一個參考。引用指的是一個「B」類型的對象,但該引用可以賦值給一個類型爲「A」的變量。一旦你把術語分類了,其餘的很多東西都會更有意義。 –

+0

我知道這裏的a2只是一個變量,並且保存了內存堆中的一個對象的引用,但是如果您可以請稍微詳細一點。 – Ozil

+0

下面是一個關於值和引用如何在Java中工作的教程:http://www.javaranch.com/campfire/StoryCups.jsp – Nayuki

回答

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(); 
1

它們是相同的。在Java中,所有對象引用都保持相同的內存量。所以相同的對象引用的內存空間可以指向任何Java對象。編譯器強制您只分配參考A以指向延伸爲A的類的對象。在上述兩種情況下,您都有一個類型爲A的引用(C中的指針),它指向B類的一個實例。

+0

那麼,第1行和第2行意味着什麼? – Ozil

+0

是的,他們是...... –

+0

幾乎是一樣的東西。第1行將對B對象的引用賦予變量a1。第2行將對另一個新的* B對象的引用賦予變量a2。初學者可能認識到如果B對象是可變的,那麼對a1的對象的改變不會影響a2s對象(因爲a1的對象和b1的對象是相同的,所以a1的對象* do *會影響b1的對象目的)。 – mwhidden

1

a2是一個引用類型[類型A],它引用了類型B的對象。那就是它,無非就是如此。

是Line1和Line2是同一件事。只是不同的方式做同樣的事情。

1

這兩者都是等價的,但唯一不同的是,在第一個中,您不必要地創建了一個Anew 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類型的變量參考那個例子。

1

兩條線都只是類似於以下

Object obj = new SomeClass(); 

但在A類型的線路1一個額外的對象被創建。

因此,與

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. 

所以本質上是相同的(除一號線額外的對象)

這兩條線在內部使用的polymorphism概念。

相關問題