简体   繁体   中英

Override methods with different generic types

I have following classes:

public class A extends Exception {
}

public class B extends Email {

}

My goal is to implement some strategy that would be able to work with both those classes like below:

For instance:

public enum Strategy {
    ACTION_1 {

        @Override
        public void handleAction(Class<? extends Exception > parameterThatShouldAcceptOnlyA) {
            throw parameterThatShouldAcceptOnlyA;
        }
    },
    ACTION_2 {

        @Override
        public void handleAction(Class<? extends Email > parameterThatShouldAcceptOnlyB) {
            parameterThatShouldAcceptOnlyB.send();
        }
    };

    public abstract void handleAction(Class<?> parameterThatShouldAcceptBoth);
}

This is not compiled through incorrect generic in overriden methods.

Could you please suggest how it would be possible to make this workable?

You better step back here. Your idea simply violates the Liskov Substitution Principle .

Basically you want to restrict a subclass in what can be passed in as argument to a method.

That breaks the whole idea that subclasses can be used in place of their superclass. Because now, all of a sudden, the code that wants to call that method has to check the type of the object it is calling on - to ensure to not call the method with "invalid" parameters.

In other words: take this compiler error as a symptom . Even when you somehow work around the specific issue; as said - you better step back and rethink your whole idea.

Hint : It is neither possible to throw a Class instance nor to invoke other methods than provided by class Class so at first you need to change your parameter type. This also let you remove the wildcards.

You can define the super class by a generic. Unfortunatelly enums do not support generics. But you can create a generic interface like

interface Handler<T> {
    void handleAction(T t);
}

and implement your handler like

class EmailHandler implements Handler<Email> {
    void handleAction(Email email) {
        email.send();
    }

class ExceptionHandler implements Handler<Exception> {
    void handleAction(Exception e) {
        // Exception is a checked exception
        // so we cannot throw it without 'throws' declaration
        // but we cannt add 'throws Exception'
        if (e instanceof RuntimeException)
            throw (RuntimeException) e;
        else
            throw new RuntimeException("wrapped", e);
    }

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