2017-03-06 58 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

相关问题