简体   繁体   中英

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
  • 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.

This isn't what generics were created for.

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.

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

public static void registerSideEffect(SideEffect) 

to keep track of the side effects that a Fish can have. The other thing you could do is in Animal, add

public void applySideEffect(SideEffect<T> effect) 

where T is your Animal generic type. This could help to limit (at static time) applying to wrong SideEffect to an Animal

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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