如何避免 instanceof 用法?

how the instanceof usage can be avoided?

我们如何避免使用 instanceof 运算符来编写干净的代码 比如说: 如果对象是 Type1,则执行某些操作,但如果它是 Type2,则执行其他操作。

if(obj instanceof T1){
    doSomething()
 }else(obj instanceof T2){
    doOtherThing()
 }

您需要在此处使用 方法覆盖 ,然后从不同 classes 的不同实例调用相同的函数,这将根据实现执行不同的指令集在个人 classes

例如,您有一个 class T,然后 class T1 和 class T2 都扩展了 class T 和所有三个 classes执行 executeTask 函数

所以,

T t1 = new T1();
T t2 = new T2();

// this will execute function overridden in T1
t1.executeTask();

// this will execute function overridden in T2
t2.executeTask();

通常,您使用一系列带有强制转换的 instanceof 来调用存在于 class 中但不存在于其他 :

中的特定方法
if(obj instanceof T1){
    ((T1)obj) doSomething();
}
else(obj instanceof T2){
    ((T2)obj) doOtherThing();
}

为避免这种情况,如果您可以修改这些 classes,T1T2 应该是公共基础 class 的子classes并且调用的方法应该在基 class.
中定义 这样,每个 subclass 都可以实现它,你可以这样写:

obj.doSomething();

如果您不能修改这些 classes,您总是可以引入一个 Adapter class 来包装它们以提供调用这些方法的通用方法。

适配器

public interface Adapter{
    void process();
}

AdapterForT1

public class AdapterForT1 implements MyAdapter{

    private T1 adapted;
    public AdapterForT1(T1 adapted){
      this.adapted = adapted;
    } 

    public void process(){
       adapted.doSomething();
    }

}

AdapterForT2

public class AdapterForT2 implements MyAdapter{

    private T2 adapted;
    public AdapterForT2(T2 adapted){
      this.adapted = adapted;
    } 

    public void process(){
       adapted.doOtherThing();
    }

}

您可以这样使用它们:

MyAdapter adapter = new AdapterForT1(obj);
...
adapter.process();

或:

MyAdapter adapter = new AdapterForT2(obj);
...
adapter.process();

创建一个 interface,两个 class 都实现了。接口是一种契约,每个实现 class 都必须遵守。

有了这个,您可以确保这样一个 class 的每个实例都实现了该接口的所有已定义方法。

例如:

public interface CustomExecutable {
    void execute();
}

然后你的两个 classes:

public class T1 implements CustomExecutable {
    @Override
    public void execute() {
        // Do t1 logic
    }
}

public class T2 implements CustomExecutable {
    @Override
    public void execute() {
        // Do t2 logic
    }
}

在你的主程序中你可以这样做:

CustomExecutable ce = new T1();
ce.execute(); // Does t1 logic
ce = new T2();
ce.execute(); // Does t2 logic

instanceof 不再是必需的,因为每种类型都有自己的 execute 编码方式。