【问题标题】:Calling suit method based on parameter type (when parameter is general or specific)根据参数类型调用西装方法(当参数是通用或特定时)
【发布时间】:2020-10-15 01:18:27
【问题描述】:

如果我有两种方法,如何调用具有特定类型而不是通用类型的方法?

我准备了两个例子:简单的和扩展的。


简单示例:

public class Testing {

    static void process(Object object) {
        System.out.println("process Object");
    }

    static void process(Integer integer) {
        System.out.println("process Integer");
    }

    public static void main(String[] args) {
        Object objectString = new String("a");
        Object objectInteger = new Integer(1);

        process(objectString); // "process Object"
        process(objectInteger); // it prints "process Object" instead of "process Integer"
    }
}

我知道我可以创建特定类型的引用:

Integer objectInteger = new Integer(1);

将调用 suit 方法。

但我想使用通用类型(最好使用List<String> list = new ArrayList<>() 而不是ArrayList<String> list = new ArrayList<>())。


扩展示例:

public class Testing {

    interface MyInterface {
    }
    static class First implements MyInterface {
        String first = "first";
    }
    static class Second implements MyInterface {
        String second = "second";
    }
    static class SpecificSecond extends Second {
        String specificSecond = "specificSecond";
    }

    public static void process(MyInterface myInterface) {
        if (myInterface instanceof First) {
            System.out.println("General case: " + ((First) myInterface).first);
        } else if (myInterface instanceof Second) {
            System.out.println("General case: " + ((Second) myInterface).second);
        } else {
            System.out.println("Should not call");
        }
    }

    public static void process(SpecificSecond specificSecond) {
        System.out.println("Specific case for SpecificSecond: " + specificSecond.specificSecond);
    }

    public static void main(String[] args) {
        MyInterface first = new First();
        MyInterface second = new Second();
        MyInterface specificSecond = new SpecificSecond();

        Testing.process(first); // "General case: first"
        Testing.process(second); // "General case: second"
        Testing.process(specificSecond); // it prints "General case: second" instead of "Specific case for SpecificSecond: specificSecond"
    }
}

我知道我能做到:

SpecificSecond specificSecond = new SpecificSecond();

但是如果不使用我的接口,我就不能使用我的其他泛型方法和类。

如何更改方法process(但不更改合同)以调用正确的方法?

我找到了解决方法(创建新的代理方法以选择正确的方法并更改通用方法的名称):

public static void process(MyInterface myInterface) {
    if (myInterface instanceof SpecificSecond) {
        process((SpecificSecond) myInterface);
    } else {
        processGeneral(myInterface);
    }
}

private static void processGeneral(MyInterface myInterface) {
    if (myInterface instanceof First) {
        System.out.println("General case: " + ((First) myInterface).first);
    } else if (myInterface instanceof Second) {
        System.out.println("General case: " + ((Second) myInterface).second);
    } else {
        System.out.println("Should not call");
    }
}

private  static void process(SpecificSecond specificSecond) {
    System.out.println("Specific case for SpecificSecond: " + specificSecond.specificSecond);
}

但是有了这个,我无法在我的 IDE 中找到特定 process(SpecificSecond) 方法的所有用法(因为它们都通过代理方法)。

还有其他解决方法可以强制调用process(SpecificSecond) 方法吗?

我怎样才能更好地设计它?

【问题讨论】:

  • 在 OOP 中,处理逻辑将存在于每个 MyInterface 实现中,并通过多态性调用。静态处理方法是过程式编程,而不是 OOP。

标签: java oop design-patterns polymorphism


【解决方案1】:

问题不是特定类型与通用类型之一,而是静态与动态绑定之一。您的示例说明了重载。 Java 使用最特定类型 选择重载方法,但基于静态 信息(即分配为参数的表达式的类型)。因为这个变量的类型是Object,所以选择了Object重载。

要实现您的目标,您必须设计代码以使用动态绑定。在这种情况下,将根据作为参数传递的 object 的最具体类型来选择方法实现。为此,您需要定义接口或实例方法,并override它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    相关资源
    最近更新 更多