简体   繁体   English

Java Generics,没有 instanceof 或转换如何做到这一点?

[英]Java Generics, how to do this without instanceof or casting?

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. 

}

When a method parameter is a superclass, what is the best way to execute subclass specific logic?当方法参数是超类时,执行子类特定逻辑的最佳方式是什么?

I'd like to avoid我想避免

  • instanceof and/or casting to the specific subclass instanceof和/或转换为特定的子类
  • adding anything to Animal/Bird/Fish向动物/鸟类/鱼类添加任何东西

Any helpful terminology for me to research would help too, cheers.任何对我研究有用的术语也会有所帮助,干杯。

If you have a reference to a superclass, then if you want to execute a specific subclass's method you MUST cast to the subclass.如果你有一个超类的引用,那么如果你想执行一个特定的子类的方法,你必须强制转换到子类。 The only time you don't is when the method is abstract in the superclass and implemented in the subclass.唯一不需要的情况是当方法在超类中是抽象的并在子类中实现时。 This is a fundamental aspect of the way inheritance works in Java.这是 inheritance 在 Java 中工作方式的一个基本方面。

This isn't what generics were created for.这不是创建 generics 的目的。

Generics were created for extended static time type checking... Basically, to warn you not to try to put a Bar object in a Foo collection. Generics 是为扩展 static 时间类型检查而创建的...基本上,警告您不要尝试将Bar object 放入Foo集合中。

the best way to design SideEffect would be as a (static or non-static) inner class. You could add a static method to Fish like设计SideEffect的最佳方法是作为(静态或非静态)内部 class。您可以向 Fish 添加一个 static 方法,例如

public static void registerSideEffect(SideEffect) 

to keep track of the side effects that a Fish can have.跟踪 Fish 可能产生的副作用。 The other thing you could do is in Animal, add您可以做的另一件事是在 Animal 中,添加

public void applySideEffect(SideEffect<T> effect) 

where T is your Animal generic type.其中 T 是您的 Animal 通用类型。 This could help to limit (at static time) applying to wrong SideEffect to an Animal这可能有助于限制(在 static 时间)将错误的 SideEffect 应用于 Animal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM