Java方法重载和调用

时间:2013-11-11 14:52:48

标签: java oop overloading

假设我有一个带有一个参数的方法,并且根据参数的类型,该方法应该做不同的事情。

让我们调用方法doMethod()

private int doMethod(Class1 x) {
    // do something with x
}

private int doMethod(Class2 x) {
   // do someting else with x
}

...

我有几种方法。现在我的问题来了: 我有一个不同的方法,它接受一个参数,它是上面所有其他类的超类(但实际上它总是它的子类之一):

private void otherMethod(SuperClass obj) {
      // I do something clever with obj, 
      // which is the super class of Class1, Class2, .. Classn
      // however this method is always called with either Class1, Class2, etc.
      // never with an instance of SuperClass itself.

      // finally I want to execute doMethod() on obj:
      int result = doMethod(obj);        

      // fails because doMethod(SuperClass) does not exist
}

最后,我最终创建了doMethod(Superclass obj),使用instanceof检查obj,然后使用强制转换调用doMethod()

必须有更好的方法来做到这一点吗?我现在想不起来,所以也许有人可以帮我解决:)

非常感谢!

2 个答案:

答案 0 :(得分:2)

有几种可能性:

子类+访客模式

您可以为每个子类创建一个子类,如果不是最终的话。您可以提供visit()方法,并使用访问者模式实施其他操作doMethod()。这将开启以后添加不同操作的可能性。访问者模式,如果做得正确,应该会忘记将操作添加到新的子类(因为它不会编译)。根据您的需要,这可能是好事,也可能不是好事。

子类是关于此之类的解决方案的一部分。这里存在爆发类层次结构和复杂性的危险:如果可能的话,我会添加最终的子类。你也遇到麻烦,你所扩展的任何课程在未来都是最终的(向后兼容性休息,但并非不可能)。

此处示例:http://www.javacodegeeks.com/2013/08/visitor-design-pattern-in-java-example-tutorial.html(在此示例中,开发人员可以访问基类并在其中添加visit()方法,而您必须将其添加到由额外子类实现的公共接口)。

聚合+访客模式

上述的一种变体是创建一个并行类层次结构,其中您自己的类包含(而不是子类)来自另一个层次结构的类的实例。您将visit()添加到您自己的类层次结构(以及您想要的任何其他方法)中,并提供访问基础类型的方法。你应该能够很好地将它包装在泛型中。

但是,这里可能存在很多复杂性。

'处理程序'的地图

您可以将操作作为实例类型键入的地图中的接口实现进行查找。

// Java-y pseudo-code...
Map<Class<? extends SuperClass>,Function<V,R>> doMethods = new HashMap<>();
doMethods.add(FooClass.class, FooDoMethod.INSTANCE);
doMethods.add(BarClass.class, BarDoMethod.INSTANCE);
...
public R doMethod(V it) {
    Class<? extends V> cls = it.getClass();
    Function<? extends V,R> fn = doMethods.get(cls);
    if(fn==null)
        throw new UnsupportedOperationException(
            "Can't doMethod() on a "+cls.getName());
    return fn.apply(it);
}

此处的INSTANCE单例对象将实现类似Java 1.8中的新Function接口(或1.8之前的可比较) - 即具有实现该操作的单个方法的接口的实现。然后,通过向地图添加更多条目来扩展支持该操作的类型。您需要为每个受支持的类型添加一个显式条目(即使是中间基类,如果它们实际上可以有实例 - 类似于Swing中的JComponent和JButton(两者都可以存在实例)。当然,您可以为多种类型添加相同的实现,如果它们以相同的方式实现它。

然后,您可以将调度隐藏到其他类中的映射处理程序(以及地图本身)。

(P.S。抱歉,手头没有javac,否则我会正确地尝试这些。)

答案 1 :(得分:0)

我怀疑我们可以在单个类中使用所有方法更清晰的方法,其他if-else阻止。我们可以将if-else移动到Factory以创建所需的实现类

public interface SomeInterface<T extends Number> {
    void doMethod(T num);
}

public class IntegerImpl implements SomeInterface<Integer> {
   @Override
    public void doMethod(Integer num) {
        // TODO Auto-generated method stub

    }

}

void otherMethod(Number n){
    SomeInterface<Number> s= SomeFactory.getObj(n);
    n.doMethod(n);
}