【问题标题】:Java abstract generic method with wild card implemented with concrete type带有通配符的 Java 抽象泛型方法用具体类型实现
【发布时间】:2018-11-03 00:24:19
【问题描述】:

是否可以在java中使用通配符定义抽象方法但在实现中使用具体类型

例如:

像这样在抽象类中定义抽象方法

public abstract class AbstractAuthorizer {
    abstract protected <T extends User> void authorize( T user );
}

像这样实现抽象方法,其中 CorporateUser 扩展 User :

public class CorporateAuthorizer extends AbstractAuthorizer {

    @Override
    protected <CorporateUser> void authorize(CorporateUser user){
    }
}

【问题讨论】:

  • 假设这个post 可以解决您的问题。

标签: java generics wildcard


【解决方案1】:

不,您不能直接执行您的要求。但是,您可以获得相同的效果。

当你做一些通用的东西时,你是在向用户做出一个承诺:这将适用于任何满足通用边界的类型。因此,通过在子类中选择特定类型,您就违反了该规则。但是,如果您正确定义了超类,那么您可以在满足类型检查器的同时获得您想要的行为。与其将函数设为通用,不如将类设为通用,然后当您对其进行子类化时,您可以选择它适用于哪种类型。

public abstract class AbstractAuthorizer<T extends User> {
    abstract protected void authorize( T user );
}

public class CorporateAuthorizer extends AbstractAuthorizer<CorporateUser> {
    @Override
    protected void authorize(CorporateUser user) {}
}

【讨论】:

  • 根据原问题假设返回类型应该是User还是错误。
  • @RajithPemabandu 在OP的问题中返回类型是void
【解决方案2】:

抽象类声明了一个方法,该方法将授权 any &lt;T extends User&gt;。您的扩展程序不符合此合同。

一些选项:

  1. 生成抽象类。

    abstract class AbstractAuthorizer<T extends User> {
        protected abstract void authorize(T user);
    }
    
    class CorporateAuthorizer extends AbstractAuthorizer<CorporateUser> {
        protected void authorize(final CorporateUser user) {
            // Do authorization.
        }
    }
    
  2. 让扩展程序执行必要的检查。类似于(AbstractAuthorizer 定义为您所拥有的):

    class CorporateAuthorizer extends AbstractAuthorizer {
        protected <T extends User> void authorize(final T user) {
            if (!(user instanceof CorporateUser)) {
                throw new UnsupportedOperationException("CorporateAuthorizer can only authorize 'CorporateUser' users");
            }
            // Do authorization.
        }
    }
    

如果您选择后者,我强烈建议您额外添加一个abstract boolean supports(User user);,它会执行上述instanceof 检查,以便它可以用作:

boolean checkAuth(final User user) {
    boolean authorized = false;
    for (final AbstractAuthorizer authorizer : authorizers) {
        if (authorizer.supports(user)) {
            authorizer.authorize(user);
            authorised = true;
            // break; if only a single authorizer's check is required.
        }
    }
    return authorised;
}

我还要注意,在后者中使用&lt;T extends User&gt; 的方法与简单地使用User 相比没有任何好处,除非您打算使用returnUser(如果获得授权)。即,

abstract class AbstractAuthorizer {
    abstract boolean supports(User user);

    abstract <T extends User> T authorize(T user);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    相关资源
    最近更新 更多