2010-05-14 120 views
2

如果我在java中有一個名爲Foo的抽象類,它有一個名爲Bar的實現者,那麼我想知道以下內容。Java中的繼承

可以說Foo看起來像

public abstract class Foo { 

    Service serviceFoo 

    ... 

} 

而且Bar

public class Bar extends Foo { 
... 
} 

此外,讓我們假設我有Foo一個實例,命名爲foo,目前已serviceFoo實例

如果我然後聲明:

Foo foo = new Bar(); 

這是否會創建一個Bar的新實例,該實例是否已經實例化了serviceFoo?例如。該字段將被繼承和實例化還是繼承?

+2

你試過了嗎? – Pops 2010-05-14 14:15:41

+0

Java區分大小寫 – 2010-05-14 14:19:12

回答

4

當您致電new Bar();時,暗示調用Foo的構造函數。如果Foo的構造函數實例化了serviceFoo,那麼Bar也是如此。如果Foo依靠其他人實例化serviceFoo,則Bar也會這樣做。

FooBar的現有實例與創建新實例時所發生的情況無關。只有在構造函數中執行的代碼(或作爲參數傳入的內容)對新對象有影響。

4

不,實例之間不會發生繼承;只在類定義之間。

當您實例化new Bar()時,serviceFoo將根據其在Foo中的聲明進行實例化。在當前情況下,它在Foo中沒有實例化,因此它將在Bar的新實例中爲空引用。

另外,您應該知道Java中的所有非基元都是引用類型。也就是說,foo不是Foo,而是對Foo的引用。當您將new Bar()指定爲foo時,您將完全重新分配其對新對象的引用。

編輯:還有一個,小的雞蛋裏挑骨頭 - 如果你已經有一個名爲foo你要求的Foo一個實例,則該行

Foo foo = new Bar(); 

不會編譯,因爲它是一個foo重複聲明。

+0

是的,我的意思是foo = new Bar()sorry:p – stevebot 2010-05-14 14:26:36

1

不,serviceFoo不會被實例化。該行

Foo foo = new Bar(); 

刪除對foo引用的「舊」對象的引用,並創建一個全新的對象。特別是,它不會將舊的foo(類型Foo)「轉換」爲Bar類型的對象。

1

當你說Foo foo = new Bar(),你正在創建一個全新的對象。這意味着Bar是從頭創建的,並且任何實例變量也都被初始化。如果它繼承自超類,如Foo,那麼這些繼承的變量也會被初始化。

無參數構造函數Bar()無法知道外部Service serviceFoo並以某種方式將其設置爲該值。

如果你想這樣做,你需要在構造函數中傳遞對serviceFoo的引用。

Foo foo1 = new Bar(); 
foo1.serviceFoo = new Service(); 
// do something with that serviceFoo 

Foo foo2 = new Bar(foo1.serviceFoo); // make sure you define this constructor 
1

由於serviceFoo是一個實例變量(即它不聲明爲static)已經把這個字段設置不會對您產生任何新的情況下,任何影響美孚的任何現有實例。

假設Bar沒有設置它,所有你會得到的是字段繼承,並沒有與新實例實例化。

1

如果你改變你的基類的代碼

public abstract class Foo { 

    Service serviceFoo = new Service(...); 
    ...... 
} 

然後欄時,欄被實例化將有服務的一個實例。

0

繼承意味着當一個子類繼承或繼承繼承類。

public class Parent { 

    public void dostuff() { 
     System.out.println("i am in parent"); 
    } 
} 

public class Child extends Parent { 

    public void dostuff() { 
     System.out.println("i am in child"); 
    } 
} 

public class Test { 

    public static void main(String[] args) { 
     Parent p = new Parent(); 
    Parent p1 = new Child(); 
     p.dostuff(); 
     p1.dostuff(); 
    } 

} 
0

繼承用於:

  1. ,使代碼的重用
  2. 促進多態性