如何在尝试扩展Java对象时避免向下转换

时间:2011-03-27 12:49:23

标签: java oop downcast

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

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

缺点是:

  • 遗失信息(私人价值)
  • 如果 Foo 发生变化,必须调整转换功能。

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

5 个答案:

答案 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似乎是一个不错的解释。