5

假设我们有一个抽象类A,我们想强制所有子类有一个特定的字段。这在 Java 中是不可能的,因为我们不能定义抽象字段。

解决方法 1:强制子类实现提供所需值的方法。

abstract class A {
  abstract int getA();
}

缺点:每个子类都必须为我们想要的每个抽象字段实现一个方法。这可能导致许多方法实现。

优点:我们可以使用getA抽象类中的方法并在其中实现方法,A而无需在每个子类中实现它们。但是方法后面的值不能被抽象类覆盖。

解决方法 2:通过强制子类给抽象类一个值来模拟抽象字段。

abstract class A {
  int a;

  public A(int a) {
    this.a = a;
  }
}

缺点:当我们有多个字段(> 10)时,超级构造函数调用看起来有点丑陋和混乱。

优点:我们可以a在抽象类中使用该字段并在其中实现方法,A而无需在每个子类中实现它们。另外,该值a可以被抽象类覆盖。

问题:哪种解决方法是达到目标的常用方法?也许有比上述更好的?

4

5 回答 5

2

抽象方法可能是最面向对象的。

如果您有太多字段,您可能希望在 POJO 中重新组合这些字段(如果适合使用新概念)。

于 2012-07-21T13:42:45.533 回答
1

我更喜欢第一个。我不喜欢在文件名中耦合类,它们如何处理状态以及如何保存它。第一个更接近打开/关闭主体

我建议避免继承。继承非常脆弱,难以维护。记住有效的 java 建议 - 更喜欢组合其他继承

于 2012-07-21T13:42:20.327 回答
0

1.其实这不是关于一个人喜欢什么,而是关于灵活性,以及​​适应变化的能力

2.将不断变化的行为封装到接口或抽象类中总是更好。

3.您的第一个解决方法将适用于您需要在不同类中对相同行为进行不同实现的地方。然后在这个地方,接口或您的第一个解决方法将是一个不错的选择。

例如:

将其Painting视为具有paint()方法的类。

现在

paint()方法可以有描边、滑动、阴影等样式。

然后最好将该方法封装到抽象类或接口中。

public interface Paint{

paintDoIt(String style);

}

4.您的第二个 Wordaround在您希望某些行为必须由子类实现的地方很好。

例如:

将Car视为一个抽象类,现在它必须具有 Steering、4 个轮子、Engine 等to be car非常重要。因此必须实现这些功能

其中音乐系统、LCD 等其他功能是可选的,具体取决于车型。

于 2012-07-21T15:03:11.210 回答
0

我认为 opt.1 是迄今为止更清洁的。一些 getter 和 setter 没什么大不了的,我怀疑许多用例不仅仅是几个抽象的“字段”。

关于 opt.2,您忘记了构造函数不是继承的,因此需要以考虑到的方式实现所有子类构造函数a

于 2012-07-21T13:41:59.657 回答
0

解决方法 2 非常常见,因为它有 2 个优点:

1)您提到的那个-该字段不属于子类-它属于父类,这很重要,因为它是父类“要求”的,并且父类可以使用它

2)当从父类子类化时,您非常了解此字段,因为当您实现构造函数时,您必须将其传递。如果我看到第一个解决方法,我不知道从中理解什么,这样我就明白父类需要这个字段才能工作,所以它必须有一个有意义的值。

注意:如果您的类有 10 个需要初始化的字段,则您的设计可能有问题。

于 2012-07-21T13:45:03.550 回答