6

我使用 GWT 和 Place & Activity 机制。

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

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

public abstract class Place {

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

}

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

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

4

4 回答 4

7

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

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

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

“界面”的意思是:这个支持

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

于 2012-04-12T12:03:22.580 回答
5

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

我想不出一个。但实际上,在 SO 上抱怨它并不会取得任何成果。

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

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

但总的来说,这是一个坏主意……IMO。

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

于 2012-04-12T12:07:06.387 回答
2

我真的不能说Place(虽然我有一些想法,见下文),但它被讨论过Activityhttps ://groups.google.com/d/topic/google-web-toolkit-contributors/V8rhZHiXFRk /讨论

就历史而言,Place一直是GWT 中的一个抽象类(和 FWIW,这个NOWHERE地方是在很久之后添加的;请注意,这个提交引用了一个 Wave——很快就会从互联网上消失——我们可以看到interface Place它是在他们设计 API 时的某个时间点的接口)。

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

免责声明:我是报告订购问题然后提供补丁的人,但Place已经是一个班级。

于 2012-04-12T16:36:49.553 回答
0

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

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

这个例子特别奇怪,因为接口是一个契约。GWTPlace没有接口,因此没有合约。他们的 javadoc 指出:

“代表应用程序中的可收藏位置”

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

于 2012-04-12T12:25:15.560 回答