2017-03-06 126 views
-1

我正在設計一個接口,爲此我打算有一個抽象類或骨架類,按照有效的Java(Joshua Bloch)項18:喜歡接口抽象類
原因是爲了防止接口的未來演變從打破實施類。在沒有實際實現任何方法的情況下,有沒有骨架類/抽象類的好設計?

截至今天,我沒有任何方法可以提供默認實現。這個設計好嗎?

如:

public interface Foo{ 
    public List<Baz> getBazList(); 
    public String getId(); 
    public String getName(); 
} 

public abstract class AbstractFoo implements Foo{ 
} 
+0

我不會有沒有方法的抽象類。它什麼也沒加。這與布洛赫的建議相反。界面就夠了。 – duffymo

+1

編號抽象類應爲所有孩子提供*共同行爲*。如果沒有什麼可與孩子分享的話,就不應該有這樣的超級班。 –

+0

對於那些低估了這個問題的人,你能說出爲什麼downvote? – user1422163

回答

1

有一個簡單但功能強大的測試,你可以在此和類似案件適用。

問自己這個問題:「我如何在我的代碼中使用這個抽象類?我打算如何處理它,以至於無法使用我的界面?

如果答案是「無」,然後擺脫它。如果一個構造沒有真正的目的,它只會給你的代碼增加混亂。

0

如果您認爲將來可能會擴展接口,從而導致子類不兼容(因爲它們不會實現這些方法),那麼使用該空的抽象超類可能是一種使它能夠輕鬆編譯的方法。

I.e.今天你

public interface Foo{ 
    public List<Baz> getBazList(); 
    public String getId(); 
    public String getName(); 
} 

public abstract class AbstractFoo implements Foo{ 
} 

public class Foo1 extends AbstractFoo { 
    public List<Baz> getBazList() { ... } 
    public String getId() { ... } 
    public String getName() { ... } 
} 

public class Foo2 extends AbstractFoo { 
    public List<Baz> getBazList() { ... } 
    public String getId() { ... } 
    public String getName() { ... } 
} 

在未來,有人改變(無論何種原因)的界面,讓您做到以下幾點:

// extended 
public interface Foo{ 
    public List<Baz> getBazList(); 
    public String getId(); 
    public String getName(); 
    public void breakMyCode(); 
} 

// provide dummy implementation for breakMyCode() 
public abstract class AbstractFoo implements Foo{ 
    public void breakMyCode() { 
    throw new RuntimeException("not implemented"); 
    } 
} 

// unchanged 
public class Foo1 extends AbstractFoo { 
    public List<Baz> getBazList() { ... } 
    public String getId() { ... } 
    public String getName() { ... } 
} 

// unchanged 
public class Foo2 extends AbstractFoo { 
    public List<Baz> getBazList() { ... } 
    public String getId() { ... } 
    public String getName() { ... } 
} 

這是一個好主意?不是真的。當接口得到擴展時,可能有一個原因,只是提供一個虛擬實現,或者什麼也不做,或者拋出一個RuntimeException不會使程序按預期工作。這是一種在編譯期間隱藏忽略的方式,但讓它們在運行時破壞程序。

+0

如果你編寫的是pre-Java 8代碼,你只有真的需要考慮這個問題,從8開始你可以在接口本身中添加默認的方法實現。 – biziclop

相關問題