使用来自作为超类实例的对象的子类的方法

时间:2014-10-09 13:28:21

标签: java inheritance

假设有一个我广泛使用的类,并由方法返回。

CommonClass obj = getCommonObject();

现在我想扩展这个类来创建一些实用方法,以避免重复自己。

public CommonClassPlus extends CommonClass {

    public String dontRepeatYourself() {
        // the reason I'm creating a subclass
    }
}

当然我想使用我改进的类来实现上述方法,但不允许进行向下转换。

CommonClassPlus obj = getCommonObject(); 
//Cannot cast to CommonClassPlus

如果我只能使用作为超类实例的对象,我该如何使用方法dontRepeatYourself()

CommonClassgetCommonObject()来自外部库,我无法更改它们。

2 个答案:

答案 0 :(得分:3)

您无法在Java中为现有实例添加行为(例如,您可以在JavaScript中添加)。

您在Java中最接近的是装饰器模式:

CommonClassPlus obj = decorate(getCommonObject());

其中decorate()

public CommonClassPlus decorate(CommonClass x) {
  return new CommonClassPlus(x);
}

这种方法创建了一个潜在的大量样板文件,因为它必须将每个方法调用委托给包装的实例。如果CommonClass中的方法是最终的,并且没有可以重新实现的接口,那么这种方法将完全失败。

在大多数情况下,您将能够使用简单的静态辅助方法:

public static String dontRepeatYourself(CommonClass x) {
   ...
}

答案 1 :(得分:2)

如果CommonClass来自外部库,您可能希望使用Adapter Pattern的原则将其包装在Composition over Inheritance中。

如果您想要更改正在使用的库,则可以完全控制,并允许您添加dontRepeatYourself()等功能。

public class CommonClassAdapter implements MyAdapter {
    private final CommonClass common;
    private final String cachedResult;

    // Note that I'm doing dependency injection here
    public CommonClassAdapter(CommonClass common) {
        this.common = common;

        // Don't expose these because they shouldn't be called more than once
        common.methodIOnlyCallOnce();
        cachedResult = common.anotherMethodIOnlyCallOnce();
    }

    @Override
    public void someMethod() {
        common.someMethodWithDifferentName();
    }

    @Override
    public String dontRepeatYourself() {
        return cachedResult;
    }
}

另请注意,大多数现代IDE都使用Eclipse Source -> Generate Delegate Methods之类的东西来加快此过程。