【问题标题】:Java Generics, how to do this without instanceof or casting?Java泛型,如何在没有instanceof或casting的情况下做到这一点?
【发布时间】:2021-01-28 19:51:17
【问题描述】:
class Animal {}

class Fish extends Animal {
    void swim() {
        // fish specific logic/side effect
    }
}

class Bird extends Animal {
    void fly() {
        // bird specific logic/side effect
    }
}

interface SideEffect < T extends Animal > {
    void mutateSomething(T);
}

class FishSideEffect implements SideEffect < Fish > {

    @Override
    void mutateSomething(Fish fish) {
        fish.swim() // swim has fish specific side effects
    }

}


void someMethod(Animal animal) {

    FishSideEffect fishSideEffect = new FishSideEffect();
    fishSideEffect(animal); // <- this won't work. 

}

当方法参数是超类时,执行子类特定逻辑的最佳方式是什么?

我想避免

  • instanceof 和/或转换为特定的子类
  • 向动物/鸟/鱼添加任何东西

任何对我有用的术语都会有所帮助,干杯。

【问题讨论】:

  • 什么是Example
  • 对不起,我已经改成SideEffect
  • 如果你有一个超类的引用,那么如果你想执行一个特定的子类的方法,你必须强制转换为子类。唯一不这样做的情况是该方法在超类中是抽象的并在子类中实现。这是 Java 中继承工作方式的一个基本方面。
  • 当然这个fishSideEffect(animal); 是行不通的。它需要一个Fish,而你传递一个Animal。在运行时,它可能是一个Fish,但在编译时这无关紧要,这将失败。
  • @JimGarrison 欢呼,这很有帮助。我想这就是它的工作原理,但想要第二个意见 - 欣赏这一点。

标签: java oop generics polymorphism


【解决方案1】:

如果您有对超类的引用,那么如果您想执行特定子类的方法,您必须强制转换为子类。唯一不这样做的情况是该方法在超类中是抽象的并在子类中实现。这是 Java 中继承工作方式的一个基本方面。

【讨论】:

    【解决方案2】:

    这不是创建泛型的目的。

    为扩展静态时间类型检查创建了泛型...基本上是为了警告您不要尝试将 Bar 对象放入 Foo 集合中。

    设计SideEffect 的最佳方式是作为(静态或非静态)内部类。您可以向 Fish 添加一个静态方法,例如

    public static void registerSideEffect(SideEffect) 
    

    跟踪鱼可能产生的副作用。您可以做的另一件事是在 Animal 中添加

    public void applySideEffect(SideEffect<T> effect) 
    

    其中 T 是您的 Animal 泛型类型。这可能有助于限制(在静态时间)将错误的副作用应用于动物

    【讨论】:

      猜你喜欢
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2019-01-18
      • 2021-02-19
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多