使用派生类型作为Java中的参数重载方法

时间:2011-07-25 10:38:44

标签: java extension-methods overloading

假设我已经扩展了现有代码,但也避免尽可能地更改代码。

在这个代码周围有一个接收某种类型的方法。

Engine.method(Base b) 

现在,我想扩展此功能。所以我将Base扩展为一个名为Derived的类型,它包含了我需要的更多数据,并且我还实现了另一个接收Derived类型并使用它做一些不同的方法。

Engine.method(Derived d)

但我不想将原来的呼叫改为“方法”。我以某种方式设法通过使用标志来实现正确的类型(Base或Derived),但由于原始调用正在使用Base,因此我的新方法将不会被调用。

Base b = null;
if(flag) {
   b = new Derived()
} else{
   b = new Base()
} 
Engine.method(b) 

问题是现在我的Engine.method(Derived d)不会被调用。我通过使用铸造

解决了这个问题
if(flag)
Engine.method((Derived)b) 

但这是错误和愚蠢的。有什么建议吗?

我总能做到:

if(flag) {
   Engine.methodForBase(new Base())
} else{
   Engine.methodForDerived(new Derived())
} 

但你能想到更好的东西吗?

由于

3 个答案:

答案 0 :(得分:4)

这是因为Java使用单一调度。这结束意味着在您的情况下,调用的方法取决于引用的类型“b”,它是Base,而不是“b”所包含的实例的类型。因此,将始终调用方法xpto。(Base b)。

你真的必须施展或使用你写的最后一种方法。

答案 1 :(得分:3)

写下这个:

class Engine {
    public static void method(Base argument) {
        if (argument instanceof Derived) {
            // ...
        }
        else {
            // ...
        }
    }
}

但可能,您应该扩展您的Engine类以允许更多的多态性,例如做这样的事情:

interface Engine<T extends Base> {
    void method(T argument);
}

并且BaseDerived的实施方式如下:

class BaseEngine implements Engine<Base> {
    @Override
    public void method(Base argument) { ... }
}

class DerivedEngine implements Engine<Derived> {
    @Override
    public void method(Derived argument) { ... }
}

答案 2 :(得分:0)

为什么不简单地用正确类型的参数调用方法?

Base b = null;
if (flag) {
    Derived d = new Derived()
    Engine.method(d); // so the correct method will be used for Derived
    b = d;
} else{
    b = new Base()
    Engine.method(b) 
}

您还可以考虑重复使用method(Base b)

public void method(Derived d) {
    method((Base)b);
    ...
}