对最终类进行子类化;或者,一个堕落的装饰者

发布于 2024-08-13 05:06:46 字数 649 浏览 7 评论 0原文

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

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

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

public class ThingFormat0 extends URI implements Thing {}

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

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

I have a number of different representations of the same kind of object; let's call it a Thing. "Thing" is a marker interface. ThingFormat0, ThingFormat1, ThingFormat2 etc. are all JavaBeans that implement Thing. (Because they are JavaBeans, a JSON marshaller automatically converts them to and from JSON automatically.) ThingFormat1 has just a few members like name and id. ThingFormat2 has URI links to other Things. In ThingFormat3 has ThingFormat1 representations of those other things etc.

The JSON serializer knows how to convert a URI automatically. (It works for any class where you can use toString() and the constructor ClassName(String string) to convert.)

I want to have a ThingFormat0 that behaves like a URI but implements the marker interface Thing.

public class ThingFormat0 extends URI implements Thing {}

This does not work because URI is a final class and can't be subclassed.

The only way I can think of to do this is by making a decorator (a very degenerate sort of decorator as it doesn't add any functionality to URI). This is easy in some "duck-typed" languages but more of a pain in Java, because I have to wrap a URI and implement all the methods of URI that I need. Is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

瑾夏年华 2024-08-20 05:06:46

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

  • 如果您使用 Eclipse,您可以为自动生成的任何字段使用委托方法。
  • 将 URI 的源复制到名为 ThingURI 的新类中。

Two simple ways I can think of:

  • If you use Eclipse, you can have delegate methods for any field generated automatically.
  • Copy the source of URI into a new class named ThingURI.
陌生 2024-08-20 05:06:46

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

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();
  }
}

Is there any reason the class can't use composition instead of inheritance?

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();
  }
}
无声静候 2024-08-20 05:06:46

您不能对最终类进行子类化。时期。

就 URI 而言,出于安全原因,几乎可以肯定它是最终的;即通过提供 URI 的偷偷摸摸的子类型(例如)允许其破坏访问控制来阻止某人破坏沙箱安全性。

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

You cannot subclass a final class. Period.

In the case of URI, it is almost certainly final for security reasons; i.e. to stop someone from breaking sandbox security by supplying a sneaky subtype of URI that (for example) allows it to subvert access control.

So yes, you'll need to use a wrapper or decorator or something like that.

渔村楼浪 2024-08-20 05:06:46
// base class that handles delegation
class BaseThing implements Thing {

   BaseThing(String uri) { ... }

   BaseThing(URI uri) { ... }

   URI getURI() { ... }

   ...
}

class ThingFormat0 extends BaseThing {
   ...
}
// base class that handles delegation
class BaseThing implements Thing {

   BaseThing(String uri) { ... }

   BaseThing(URI uri) { ... }

   URI getURI() { ... }

   ...
}

class ThingFormat0 extends BaseThing {
   ...
}
输什么也不输骨气 2024-08-20 05:06:46

您发现这很困难,因为您的 ThingFormat 类型不是 URI。它们公开 URI 并且可以对应于 URI,但这并不意味着它们就是 URI。也许您渴望实现继承,但是接口继承在这里失败,因为这不是一个正确的is-a关系;它未能通过LSP

例如,考虑一下 ThingFormat 是否具有方案或片段组件,或者是否可以根据某些基本 URI 进行解析。这些是 URI 的方面和操作,与 ThingFormat 没有太多关系,无论它做什么。

You're finding this is difficult because your ThingFormat types are not URIs. They expose URIs and can correspond to URIs, but that does not make them URIs. Perhaps you're pining for implementation inheritance, but interface inheritance fails here because this is not a proper is-a relationship; it fails the LSP.

Consider, for example, whether a ThingFormat has a scheme or a fragment component, or if one can be resolved against some base URI. Those are facets and operations of URIs that don't have much to do with ThingFormat, whatever it happens to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文