我应该对应该由子类指定的数据使用抽象方法还是实例变量?

时间:2011-02-01 14:48:08

标签: java variables abstract-class

我正在编写一个抽象类,我有一个应该由子类定义的变量(在这种情况下,它是一个在超类中使用的int)。我无法决定是否使用默认值定义protected变量,并让子类在构造函数中或通过setter方法更改值。或者在父类中定义一个抽象方法,以便所有子类必须实现它并返回它们想要使用的值(然后使用抽象方法访问超类中的方法)。任何人都可以告诉我,为什么一种方式优先于另一种方式有什么好的理由呢?

抽象方法:

public abstract int getValue();

public int getValue() {
    return 5;
}
  • 优点:

强制子类考虑这个值并选择他们想要的值。

  • 缺点:

没有默认值,因此即使大多数子类只想使用相同的值,他们仍然必须实现该方法。 (该方法可以是非抽象的并返回默认值,但是你失去了强迫子类思考值的优势)

受保护的变量:

protected int value;

public SubClassImpl() {
    value = 5;
}
  • 优点:

可以定义默认值,如果子类不关心,子类可以忽略它。

  • 缺点:

子类的作者没有意识到变量的存在,因此他们可能会对默认行为感到惊讶。

2 个答案:

答案 0 :(得分:8)

嗯,这取决于......

  • 该值是否必须能够在对象的生命周期内更改?如果没有,您可能希望将其设为受保护的构造函数参数,并使其成为基类中的最终私有变量。

  • 可能的子类有理由根据其他可变状态计算变量吗?如果是这样,抽象的吸气剂将是合适的。

  • 否则,我可能会使用私有变量和受保护的setter。我一般不喜欢非私人变量。这可以允许您对基类中值的更改做出反应,例如更改其他计算机字段。为了避免出现默认值,您可以将其与构造函数参数结合使用,以强制初始值,子类可以稍后通过setter更改。

答案 1 :(得分:0)

我通常使用抽象方法,因为这样可以利用covariant return types但(可变)字段或属性不会。

例如,在Guava中,{}允许ForwardingSortedMap扩展ForwardingMap