简体   繁体   English

覆盖具有不同泛型类型的方法

[英]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 . 您的想法完全违反了Liskov替代原则

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. 提示 :不能抛出Class实例,也不能调用Class提供的其他方法,因此,首先需要更改参数类型。 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);
    }

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

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