类层次结构中的Java可选接口

时间:2012-06-18 19:15:01

标签: java inheritance interface styles

假设您有一个约30个类的Java类层次结构,其中包含基类BaseClass和两个主要子类(SubclassA,SubclassB),每个子类具有多个子类。其中一些子类具有某种行为。假设你可以“戳”它们,改变它们的状态。 (这是向现有层次结构添加行为的新要求。“Poke”对大多数类来说毫无意义。)

interface Pokeable {
  void poke();
  int getTimesPoked();
}


public class Pokey extends SubclassB 
implements Pokeable {
  private int timesPoked = 0;
  public void poke() {
    timesPoked++;
  }
  public int getTimesPoked() {
    return timesPoked;
  }
}

是否应该通过仅在那些需要它的类中实现Pokeable来完成,然后在所有必须戳掉任何可以被攻击的对象的代码中执行以下操作?

public void process(BaseClass b) {
  if (b instanceof Pokeable) {
    ((Pokeable)b).poke();
  }
}

或者整个层次结构是否应该实现Pokeable以便为那些真正可以破解的人?

interface Pokeable {
  void poke();
  int getTimesPoked();
  boolean isReallyPokeable();
}

public class BaseClass implements Pokeable {
  public void poke() {}
  public int getTimesPoked() { return 0; }
  public boolean isReallyPokeable() { return false;}
}

public class Pokey {
  private int timesPoked = 0;
  @Override
  public void poke() {
    timesPoked++;
  }
  @Override
  public int getTimesPoked() {
    return timesPoked;
  }
  @Override
  public boolean isReallyPokeable() {
    return true;
  }
}

public void process(BaseClass b) {
  b.poke();
}

编辑补充:这是一个双重调度问题。 “扑克”代码对某个对象执行某些操作时,如果该对象是“可戳”的,则必须调用“poke()”,否则不能。你是否“戳()”取决于是否想要戳戳以及物体是否接受戳戳。我可以使用访客模式,但这似乎使它更复杂。

3 个答案:

答案 0 :(得分:4)

如果一个类不可用,我建议不要实现Pokeable接口,因为这会让人感到困惑。

改为采用以下方法之一。

  • 创建一个实现BaseClass的{​​{1}}的抽象或具体子类,并让所有你想成为的Pokable子类扩展它。如果通过所有实现类中的相同逻辑实现Pokeable,则此方法很有效。
  • 让每个子类单独实施poke()

答案 1 :(得分:2)

我认为通过一个名为“isReallyX”的方法是一个警示标志。如果有人一眼就看到一个类并且发现它是“Pokeable”,他们可能会试图戳它并最终出现意外行为,因为它不是真的可以攻击。

我会采取你以前的做法,不会误导外部程序员(或者在你忽略这段代码两个月后自己!)

答案 2 :(得分:0)

如果您不想实现父类的所有方法,那么您的子类可能是抽象的。但....

  

或者整个层次结构应该为了实现Pokeable而实现   很少有人真的很可爱吗?

绝对没有......不可修改的类不应该实现可扩展的接口。

  

这应该通过仅在那些类中实现Pokeable来完成   需要它,然后在所有必须戳的代码中执行以下操作   任何可以捅的对象?

这是一个稍好的模型......但是,这是一个非常程序化的设计。

还可以将<Pokeable>对象的集合保留在某处,然后快速遍历该集合以将其全部戳出来?

您是否可以通过事件发送器注册可扩展类? ......所以当某个事件发生时,所有的课程都被戳了?