【问题标题】:Why to use an empty abstract class instead of an interface?为什么要使用空的抽象类而不是接口?
【发布时间】:2012-04-24 18:33:37
【问题描述】:

我使用 GWT 和 Place & Activity 机制。

很遗憾 Place 是一个类,因为我的自定义位置不能扩展另一个类。

当我查看地方代码时,我看到以下内容:

public abstract class Place {

  /**
   * The null place.
   */
  public static final Place NOWHERE = new Place() {
  };

}

这样看来,Place 可以是一个界面。 GWT 团队选择将 Place 设为抽象类而不是接口是否有充分的理由?

概括一下:创建真正空的抽象类与接口是否有充分的理由?

【问题讨论】:

  • 接口也可以有常量,所以NOWHERE常量不会影响它是接口还是抽象类的决定。
  • @Christopher:你是对的。我编辑我的帖子。给投反对票的客人:请给我提示以改进我的问题,我不明白你为什么投反对票。
  • @Martijn Courteaux 可能是故意破坏或思维定势的盖世太保。这是SO的普遍现象

标签: java gwt interface abstract-class


【解决方案1】:

一般我不会定义一个空的抽象类

但是,当我期望将来有一些成员时,我可能会决定使用抽象类而不是接口

“类”的意思是:这是一个

“接口”的意思是:这个支持

对于“地点”,我真的可以看到两者都有一点直观的类偏好

【讨论】:

  • 当你说“期望一些成员”时,你的意思是“期望一些对象”吗?
  • @Aditya Naidu 不,我的意思是成员方法或成员字段
【解决方案2】:

GWT 团队选择将 Place 设为抽象类而不是接口是否有充分的理由?

我想不出一个。但说实话,在 SO 上抱怨它不会有任何收获。

概括一下:创建真正空的抽象类与接口是否有充分的理由?

假设您这样做是为了确保有一个通用基类来满足未来的预期需求……或出于其他原因。

但一般来说这是个坏主意……IMO。

(当然,由于历史原因,此类事情经常发生;例如,abstract 类过去可能有更多成员已被删除。)

【讨论】:

  • 感谢您的回答,我不是在抱怨,我只是想了解一下,因为我认为 Gwt 团队通常会选择好的设计,而这个让我感到不安。
  • 没有人是完美的。别担心。
  • +1 出于历史原因……当您不了解历史(以及为满足各种要求而做出的权衡)时,很容易批评设计。
【解决方案3】:

我不能代表 GWT 团队发言,但这个抽象类的唯一原因似乎是强制定义 NOWHERE。

正如您所发现的,以这种方式使用抽象类会迫使您进入一个可能不适合您的业务模型的类层次结构。 因此,一般来说,如果抽象类真的完全是空的,那根本就没有目的。

这个例子特别奇怪,因为接口是一个契约。 GWT Place 没有接口,因此没有合约。他们的 javadoc 声明:

“表示应用中的可收藏位置”

我本来希望定义一些合同来处理这种情况。可添加书签的位置需要哪些方法?如果这只是一个标记,比如Serializable,我肯定希望它是一个接口而不是一个抽象类。

【讨论】:

    【解决方案4】:

    对于Place,我真的说不出来(虽然我有一些想法,见下文),但对于Activity 进行了讨论:https://groups.google.com/d/topic/google-web-toolkit-contributors/V8rhZHiXFRk/discussion

    就历史而言,Place 在 GWT 中有 always been 一个抽象类(和 FWIW,NOWHERE 位置已添加 long after;请注意,此提交引用了 Wave -soon to消失来自互联网——我们可以在其中看到interface Place,因此在他们设计 API 的某个时间点,它是一个接口)。

    鉴于PlaceHistoryGenerator(当您使用GWT.create()PlaceHistoryMapper 时使用)查看位置层次结构,拥有一个抽象类可以减少很多极端情况!
    想象一下您的PlaceHistoryMapper 引用了PlaceTokenizers<Foo>PlaceTokenizer<Bar>,而您有一个class FooBar implements Foo, Bar { },应该使用哪个标记器?如果您没有在PlaceHistoryMapper 中明确引用FooBar 类,生成器将看不到它(或者更确切地说不会看到它),那么它应该生成哪种代码?请记住,我们都想要确定性,因此生成的代码应该始终相同。使用一个类,生成器可以通过它们的继承树(从最具体的——最衍生的——到最不具体的)对它们进行排序,并且可以安全地假设类没有特定继承关系的 2 个地方是完全不同的,所以它们可以是以任何顺序检查(生成的代码中的instanceof)并且仍然提供稳定的结果⇒确定性。

    免责声明:我是reported 订购问题然后provided the patch,但Place 已经是一个类。

    【讨论】:

    • 谢谢你的回答,这是最清楚最有道理的一个。我验证它。
    猜你喜欢
    • 2020-07-06
    • 2012-08-20
    • 2013-09-21
    • 1970-01-01
    • 2014-07-23
    • 2011-01-10
    • 2018-07-19
    • 1970-01-01
    • 2017-03-14
    相关资源
    最近更新 更多