我通过调用外部API获得了几个 Foo 类型的对象。在本地我想用一些附加信息来处理这些对象,所以我有一个子类 FooSon ,它添加了那些额外的字段。如何将我得到的所有对象转换为新的继承类型?向下转换似乎不是一种选择,因为这些对象实际上不是 FooSon 。
我提出的唯一解决方案是创建一个转换函数,该函数将 Foo 对象作为参数,然后将所有公共/受保护值复制到新的 FooSon 然后返回的对象。
缺点是:
Class Foo没有实现复制构造函数或克隆运算符。我有Foo源代码,但我想避免更改它以保持与未来版本的兼容性。然而,如果它是唯一可行的替代方案,我会改变Foo实现以获得我需要的东西。
答案 0 :(得分:4)
FooSon可能会有一个Foo字段。然后只需将返回的值分配给该字段。然后,您可以在Fooson中创建方法,将其调用委托给Foo字段,以便从外部获取Foo所需的信息。
答案 1 :(得分:4)
我认为装饰模式应该适用于此:
class Foo implements FooApi {...}
class FooSon implements FooApi {
private FooApi decoratedFoo;
private String additional;
public FooSon(FooApi decoratedFoo) {
this.decoratedFoo = decoratedFoo;
}
...
}
但只有当你的Foo对象有接口时才能这样做。
答案 2 :(得分:0)
也许我还没有完全理解这个问题,但是为什么不将Foo(继承)子类化,而不是像FooSon(组合)中的字段类型一样存储Foo?
在任何情况下,如果您无法将访问控制修改为Foo类型,因为对象已定义到外部库中,则无法直接访问私有字段(这正是私有字段的属性)。如果可以从getter和setter方法访问这些私有字段,那么将这些方法包装在FooSon类中。
答案 3 :(得分:0)
嗯,正如你已经发现,在这种情况下,铸造不适用。我看到以下选项:
外部库提供了一些工厂机制,您可以使用它来实例化FooSon
而不是Foo
。
收件人在{{1}}个对象中包装Foo
个对象,可能使用委托者模式。
通过使用以FooSon
为关键字的地图,收件人在逻辑上将附加信息附加到Foo
个对象。
答案 4 :(得分:0)
你不应该贬低,你不能保证它会成功,并且有更好的方法来处理这个问题。 例如,您可以将Foo对象包装在另一个类中,并将适当的方法调用委托给Foo对象。
我建议你花一些时间来确保你理解一些基本的OO概念。 特别是谷歌的“构图与继承”,这link似乎是一个不错的解释。