如何避免 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,T1
和 T2
应该是公共基础 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
编码方式。
我们如何避免使用 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,T1
和 T2
应该是公共基础 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
编码方式。