java 如何避免instanceof

mefy6pfw  于 2023-11-15  发布在  Java
关注(0)|答案(2)|浏览(127)

我有接口AAA。我有两个类(实体):
public class BBB implements AAA
public class CCC implements AAA
当然,这两个类都有不同的字段,将在Service中使用。
我有服务:

public class Service() {
    public DDD returnDdd(AAA aaa){
        ....
        return method1(aaa);
    }
    private DDD method1(AAA aaa){
        if(aaa instanceof BBB){
            return method2(aaa)
        }
        return method3(aaa)
    }
}

字符串
如何避免instanceof?在我的Service中,我为BBBCCC提供了公共逻辑。Method1Method2在此服务中使用相同的私有方法。

50few1ms

50few1ms1#

在这种情况下,我建议在接口AAA中使用一个通用方法,如:

public interface AAA {
    void method1();
}

字符串
并使两个继承的类都实现这个方法。在这种情况下,你只需要调用一个方法,这个方法将根据确切的示例自动选择。

public class Service() {
    public void ddd(AAA aaa){
        aaa.method1();
    }
}

...

public class Main {
    public static void main(String[] args) {
        AAA b = new BBB();
        AAA c = new CCC();

        new Service().ddd(b); // b.method1() will be called
        new Service().ddd(c); // c.method1() will be called
    }
}

zlwx9yxi

zlwx9yxi2#

好吧,这可能是非正统的,但它的工作,除非有一些其他的要求,是从您的代码失踪。我没有使用接口AAA方法的任何东西,但可以添加如果需要。
但是我真的不认为使用instanceof有任何问题。

class Service {    
    public DDD returnDDD(AAA aaa) {
        return switch(aaa.getClass().getSimpleName()) {
            case "BBB" -> method2((BBB)aaa); // casting depends on method
                                             // signatures
            case "CCC" -> method3((CCC)aaa);
            default -> null; // or some appropriate return value.
        };
    }
    public DDD method2(BBB b) {
        System.out.println("Calling method2");
        return new DDD();
    }
    public DDD method3(CCC c) {
        System.out.println("Calling method3");
        return new DDD();
    }
}

字符串
指纹

calling method2
calling method3


下面是我如何稍微修改你现有的代码。它将AAA转换为适当的子类型,这样你就可以利用每个类的属性。增强的instanceof有助于这一点。

class Service {
    public DDD returnDDD(AAA aaa){
        return method1(aaa);
    }
    private DDD method1(AAA aaa){
        if(aaa instanceof BBB bbb){ // bbb cast for you
            return method2(bbb);
        }
        return method3((CCC)aaa); // do it explicitly
    }
}


以上假设method2method3可以接受子类型作为基于方法签名的参数。否则,它们可能需要在内部转换到方法以访问子类型属性。

相关问题