在没有实际实现任何方法的情况下拥有骨架类/抽象类是不是很好的设计?

时间:2017-03-06 10:04:20

标签: java interface abstract-class

我正在设计一个接口,我打算按照有效Java (Joshua Bloch)来获得一个抽象类或骨架类。第18项:首选接口到抽象类
原因是为了防止界面的未来发展破坏实施类。

截至今天,我没有任何方法可以为其提供默认实现。这个设计好吗?

例如:

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

public abstract class AbstractFoo implements Foo{
} 

2 个答案:

答案 0 :(得分:1)

您可以在此案例和类似案例中应用简单但功能强大的测试。

问自己这个问题:“我如何在我的代码中使用这个抽象类?我打算如何使用我的界面无法使用它?”

如果答案是“没有”,那么就摆脱它。如果构造没有任何实际意义,它只会给代码增加混乱。

答案 1 :(得分:0)

如果您认为将来可能会扩展接口,从而导致子类不兼容(因为它们没有实现这些方法),那么使用该空的抽象超类可能是一种使其能够轻松编译的方法。 / p>

即。今天你有

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的虚拟实现不会使程序按预期工作。它是一种在编译期间隐藏省略的方法,但让它们在运行时中断程序。