【问题标题】:Avoid using instanceOf in observer method避免在观察者方法中使用 instanceOf
【发布时间】:2023-04-07 11:03:01
【问题描述】:

我有以下 Java 系统:

public class Human {
     public void drown(Animal animal) {
          if (animal instanceOf Fish) {
              return;
          } else {
              animal.die();
          }
     }
}

public abstract class LandAnimal extends Animal{...}
public class Tiger extends LandAnimal{...}

public abstract class Fish extends Animal {...}
public class Trout extends Fish {...}

我想过添加一个方法

public abstract boolean drownable() {...}

在 Animal 类中,但我无权访问 Animal 类的代码。 据我所知,使用 instanceOf 被认为是不好的 OOP 做法。在这种情况下如何避免使用 instanceOf ?谢谢。

【问题讨论】:

  • 为什么不在Animal 上使用抽象的.drowned() 方法?方法可以什么都不做
  • 您在寻找访客模式吗?
  • 溺水动物不爽=(
  • 哇是Human#drown中的代码写if (!(animal instanceof Fish)) { animal.drown(); }的复杂方式;-)
  • 反对票似乎很苛刻。

标签: java oop instanceof


【解决方案1】:

Human 中的drown() 方法应该是(顺便问一下,人类为什么要淹死动物?):

 public void drown(Animal animal) {
      animal.drown();
 }

而且每个Animal都会知道该怎么做,例如:

// in class Tiger
public void drown() {
    die();
}

// in class Fish
public void drown() {
    // do nothing, fish can't drown
}

【讨论】:

  • +1,但这只有在 Animal#drown 被重命名时才有意义。 Animal#immerseInWater 或类似的。因为鱼不会淹死在水里。
  • Fish 中的 return; 是多余的:p
  • @T.J.Crowder 我假设所有动物都实现相同的接口,其中包括drown() 方法
【解决方案2】:

您将声明 Animal.drown() 并在 Fish 中覆盖它,其中包含适当的“终止代码”:)。 因此,您只需要在每只动物上调用 drown(),每个实例都会根据其类型特定的方法实现来表现。

public class Human {
     public void drown(Animal animal) {
         animal.drown();
     }
}

【讨论】:

    【解决方案3】:

    方法可以根据它们的参数重载。你可以有两种不同的方法:

    public void drown(Fish f) {
      return;
    }
    
    public void drown(LandAnimal a) {
      a.drown();
    }
    

    但是,应该注意的是,这使得确定某些动物是否会淹没 Human 类的责任,正如其他答案所示,这是有争议的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 2022-11-15
      • 1970-01-01
      • 2011-09-03
      • 2013-03-05
      • 2012-11-09
      • 1970-01-01
      相关资源
      最近更新 更多