3

我对同一种对象有许多不同的表示;让我们称之为事物。“事物”是一个标记界面。ThingFormat0、ThingFormat1、ThingFormat2等都是实现Thing的JavaBean。(因为它们是 JavaBean,所以 JSON 编组器会自动将它们与 JSON 进行自动转换。) ThingFormat1 只有几个成员,例如 name 和 id。ThingFormat2 具有指向其他事物的 URI 链接。在 ThingFormat3 中有 ThingFormat1 表示其他事物等。

JSON 序列化程序知道如何自动转换 URI。(它适用于任何可以使用 toString() 和构造函数 ClassName(String string) 进行转换的类。)

我想要一个行为类似于 URI 但实现标记接口 Thing 的 ThingFormat0。

public class ThingFormat0 extends URI implements Thing {}

这不起作用,因为 URI 是最终类并且不能被子类化。

我能想到的唯一方法是制作一个装饰器(一种非常退化的装饰器,因为它不会向 URI 添加任何功能)。这在一些“鸭子类型”语言中很容易,但在 Java 中更痛苦,因为我必须包装一个 URI 并实现我需要的所有 URI 方法。有没有更简单的方法?

4

5 回答 5

3

我能想到的两种简单方法:

  • 如果您使用 Eclipse,您可以为任何自动生成的字段设置委托方法。
  • 将 URI 的源复制到名为 ThingURI 的新类中。
于 2009-12-06T04:04:21.337 回答
2

该类有什么理由不能使用组合而不是继承?

public class ThingFormat0 implements Thing {
  private final URI uri;

  public ThingFormat0(String uri) { this.uri = URI.create(uri); }

  public ThingFormat0(URI uri) { this.uri = uri; }

  public URI getUri() { return uri; }

  @Override public String toString() {
    return uri.toString();
  }
}
于 2009-12-06T15:33:45.683 回答
1

您不能子类化最终类。时期。

在 URI 的情况下,出于安全原因,它几乎肯定是最终的;即通过提供一个偷偷摸摸的 URI 子类型(例如)允许它破坏访问控制来阻止某人破坏沙盒安全性。

所以是的,你需要使用包装器或装饰器或类似的东西。

于 2009-12-06T04:00:38.427 回答
0
// base class that handles delegation
class BaseThing implements Thing {

   BaseThing(String uri) { ... }

   BaseThing(URI uri) { ... }

   URI getURI() { ... }

   ...
}

class ThingFormat0 extends BaseThing {
   ...
}
于 2009-12-06T16:07:32.587 回答
0

您发现这很困难,因为您的ThingFormat类型不是URI。它们公开 URI 并且可以对应于 URI,但这并不能使它们成为 URI。也许您正在为实现继承而苦苦挣扎,但是接口继承在这里失败了,因为这不是正确的is-a关系;它使LSP失败。

例如,考虑 a 是否ThingFormat具有方案或片段组件,或者是否可以针对某个基本 URI 进行解析。这些是 URI 的方面和操作,与 没有太多关系ThingFormat,不管它发生了什么。

于 2009-12-06T16:39:52.387 回答