4

我从对外部 API 的调用中获得了几个Foo类型的对象。在本地,我想用一些附加信息来处理这些对象,所以我有一个子类FooSon来添加这些额外的字段。如何将我获得的所有这些对象转换为我的新继承类型?向下转换似乎不是一种选择,因为这些对象并不是真正的FooSon

我想出的唯一解决方案是创建一个转换函数,它将Foo对象作为参数,然后将所有公共/受保护的值复制到一个新的FooSon对象,然后返回该对象。

缺点是:

  • 丢失信息(私人价值)
  • 如果Foo改变了,必须调整转换函数。

Foo 类不实现复制构造函数或克隆运算符。我有 Foo 源代码,但我想避免更改它以保持与未来版本的兼容性。不过,如果它是唯一可行的选择,我会更改 Foo 实现以获得我需要的东西。

4

5 回答 5

4

FooSon 中可能有一个 Foo 字段。然后只需将返回的值分配给该字段。然后,您可以在 Fooson 中创建方法,将它们的调用委托给 Foo 字段,以获取您需要从外部 Foo 获取的信息。

于 2011-03-27T12:54:19.833 回答
4

我认为装饰器模式应该在这里工作:

class Foo implements FooApi {...}

class FooSon implements FooApi {
    private FooApi decoratedFoo;
    private String additional;

    public FooSon(FooApi decoratedFoo) {
        this.decoratedFoo = decoratedFoo;
    }
    ...
}

但只有当您有 Foo 对象的接口时,您才能执行此操作。

于 2011-03-27T13:15:18.263 回答
0

也许我还没有完全理解这个问题,但是为什么你不将 Foo 存储为 FooSon (组合)中的字段类型而不是子类化 Foo (继承)?

无论如何,如果由于对象被定义到外部库中而无法将访问控制修改为 Foo 类型,则无法直接访问私有字段(这正是私有字段的属性)。如果可以从 getter 和 setter 方法访问这些私有字段,则将这些方法包装在您的 FooSon 类中。

于 2011-03-27T12:55:13.910 回答
0

好吧,正如您已经发现向下铸造在这种情况下不适用。我看到以下选项:

  • FooSon外部库提供了一些工厂机制,您可以使用它来使其实例化Foo

  • 接收者将对象包装FooFooSon对象中,可能使用委托者模式。

  • Foo接收者通过使用带有Fooas 键的映射在逻辑上将附加信息附加到对象。

于 2011-03-27T12:55:50.447 回答
0

你不应该沮丧,你不能保证它会成功,并且有更好的方法来处理这个问题。一方面,您可以将 Foo 对象包装在另一个类中,并将适当的方法调用委托回 Foo 对象。

我建议您花一些时间来确保您了解一些基本的 OO 概念。特别是,谷歌的“组合与继承”,这个链接似乎是一个不错的解释。

于 2011-03-27T13:00:41.120 回答