【问题标题】:Multiple instanceof in a if statementif 语句中的多个 instanceof
【发布时间】:2014-10-16 13:01:59
【问题描述】:

我有一个 if 语句,带有多个 instanceof 检查。示例:

if (object instanceof Object1) {
    // do something
} else if (object instanceof Object2) {
    // to something else
} else if (object instanceof Object2) {
    // and something else
} ...

解决这个 if-else-query 的更优雅的方法是什么?

【问题讨论】:

标签: java if-statement instanceof


【解决方案1】:

OOP 中的最佳实践是将逻辑放入object 本身并使其实现接口:

界面:

public interface MyLogic{
    public void doLogic();
}

第一个对象:

public class Object1 implements MyLogic{
  public void doLogic(){// logic 1 here}
}

第二个对象:

public class Object2 implements MyLogic{
  public void doLogic(){// logic 2 here}
}

现在只需将您的逻辑移动到对象本身,而不是所有 if 语句都只使用

object.doLogic(); // make sure object is from type MyLogic, if not, cast it

【讨论】:

  • 问题是,我无权更改 Object1、Object2 等。它们实现接口是不可能的。还有其他解决方案吗?
  • 您可以使用 java 反射并使用从类名派生的方法创建一个类并使用反射运行它们
【解决方案2】:

这似乎是多态性,因此您可以创建一个接口并为每个对象实现它。

interface ObjectToBeImplemented{
 method();
}

class Object1 implements ObjectToBeImplemented{ 
 @Override
 method(){...}
}
class Object2 implements ObjectToBeImplemented{ 
 @Override
 method(){...}
}

class Object3 implements ObjectToBeImplemented{ 
 @Override
 method(){...}
}

【讨论】:

  • 嗯,我怀疑Object 是否是接口名称的好选择(即使它只是一个示例):-)
【解决方案3】:

这是接口的典型用法。将接口视为定义实例的类型。因此,您知道某个类型的所有实例都可以执行特定任务。那时,您并不真正关心对象的具体类,您只知道它具有可供您使用的特定接口。

例子:

public interface Worker {
     public void doWork();
}

public class Object1 implements Worker {
    public void doWork() {
      // work for this specific object
    }
}

public class Object2 implements Worker {
    public void doWork() {
      // work for this specific object
    }
}

public class Object3 implements Worker {
    public void doWork() {
      // work for this specific object
    }
}

那么你的 if 语句将被替换为

obj.doWork();

【讨论】:

    【解决方案4】:

    这感觉就像错过了多态性的机会。

    这是一堆类与其超类/接口共享相同方法签名的地方,因此调用它的代码不需要知道它是哪种类型。

    没有多态性:

    Employee employee = ...;
    if(employee instanceof Doctor) {
         salary = calcDoctorSalary(...);
    } else if(employee instanceof Nurse) {
         salary = calcNurseSalary(...);
    }
    

    具有多态性:

    Employee employee = ...;
    salary = employee.calcSalary(...);
    

    魔法进入子类。 calcSalary() 在超类中是抽象的,或者是接口中的方法签名:

    public abstract class Employee {
         public abstract int calcSalary(...);
    }
    

    ...或...

    public interface Employee {
        public int calcSalary(...);
    }
    

    然后依赖类型的逻辑进入子类:

    public class Nurse implements Employee {
        @Override
        public int calcSalary(...) {
             // code specific to nurses goes here.
        }
    }
    

    无论是扩展一个类,还是实现一个接口,你都将通过经验来学习。通常当一个人没有从一个界面开始时,一个人以后会后悔。

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 2017-03-08
      • 2015-09-24
      相关资源
      最近更新 更多