2010-05-15 149 views
7

我讀的書 - Hadoop: The Definitive GuideJava接口和抽象類的問題

在第2章(第25頁)中,提及「新的API有利於通過接口抽象類,因爲這些更容易演變爲。例如,您可以將一個方法(使用默認實現)添加到抽象類中,而不會破壞該類的舊實現「。這意味着什麼(尤其是什麼意思是「破壞班級的老練」)?欣賞是否有人能向我展示一個樣本,爲什麼從這個角度來看抽象類比接口更好?

由於事先 喬治

回答

10

在一個接口的情況下,在接口定義的所有方法必須由實現其一個類來實現。

鑑於接口甲

interface A { 
    public void foo(); 
} 

和一類B:

class B implements A { 
} 

必須提供一種用於在接口中定義的方法的實現:

class B implements A { 
    @Override 
    public void foo() { 
     System.out.println("foo"); 
    } 
} 

否則,這是一個編譯時錯誤。現在採取的抽象類與方法的默認實現:

abstract class C { 
    public void bar() { 
     System.out.println("bar"); 
    } 
} 

其中一類從這個抽象類繼承可以是這樣的:

class D extends C { } 

沒有一個錯誤。但是如果它傾向於這樣做,它也可以重寫默認的方法實現。如果你的API還不穩定,你需要修改接口(是的,抽象類也是接口(在OOP中說)),那麼抽象類允許你添加東西而不會破壞已經存在的類。但是,這隻適用於非抽象方法。如果添加抽象方法,那麼它們仍然需要在每個派生類中實現。但是,如果您的API仍在不斷髮展並且已經有很多東西在構建,那麼它可以讓您的生活更輕鬆。

+0

謝謝!我很困惑的是這本書 - 「在課堂上突破舊課程的實施」。 「類」是指類是從抽象類或抽象類所基於的類派生的? – George2 2010-05-15 14:16:45

+1

@George:它表示從舊版本的接口/抽象類派生的類。使用接口它不再有效,因爲它無法實現您添加到接口的方法。有了抽象類和非抽象方法,它可以在不知道它在那裏的情況下,愉快地使用基類的實現。 – Joey 2010-05-15 14:18:54

+0

謝謝!你的意思是假設在版本1中,抽象類具有方法Foo,並且類從派生自抽象類的實現Foo。在抽象類的第2版中,添加了一個新的方法Goo,派生類仍然可以工作而不受影響(如果Goo在抽象類中有默認實現)? – George2 2010-05-15 14:26:19

6

如果添加一個方法用默認實現一個抽象類,什麼都不需要在任何派生類改變。

或者,如果向接口添加方法,則實現該接口的任何類都需要實現該方法 - 否則它們將不會編譯。

+0

謝謝! 「任何基類中什麼都不需要改變」 - 「任何基類」,你是指抽象類的基類,還是從抽象類派生的類? – George2 2010-05-15 14:14:13

+1

該死的。我應該留下這些例子。再花4分鐘時間;-) – Joey 2010-05-15 14:15:16

+0

我上面評論的任何答案? :-) – George2 2010-05-15 14:18:58

1

請同時參閱從Eclipse的維基以下原則

基於Java的演變的API

Adding an API method

例4 - 添加API方法

可以加入一個API方法到一個類或接口是否與現有客戶端兼容?

如果該方法被添加到客戶端可能實現的接口,那麼它絕對是一個突破性的改變。

如果將該方法添加到不允許客戶端進行子類化(實現)的類(接口),那麼這不是一個重大更改。

但是,如果該方法被添加到客戶端可以繼承的類中,那麼通常應將該更改視爲突變。這個嚴厲的結論的原因是因爲客戶的子類可能已經有了它自己實現的那個名稱的方法。將API方法添加到超類中會削弱客戶端的代碼,因爲如果客戶端的現有方法符合新添加方法的API合約,那將非常巧合。在實踐中,如果這種名稱重合的可能性非常低,那麼這種改變常常被視爲沒有破裂。