使用具体类型

时间:2017-07-16 00:45:43

标签: java generics wildcard

在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){
    }
}

2 个答案:

答案 0 :(得分:4)

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

当你制作通用的东西时,你会向用户做出承诺:这适用于满足通用界限的任何类型。因此,通过在子类中选择特定类型,您将违反该规则。但是,如果您正确定义了超类,那么您也可以在满足类型检查器的同时获得所需的行为。而不是使函数通用,使类成为泛型,然后当你子类化它时,你得选择它所使用的类型。

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) {}
}

答案 1 :(得分:1)

抽象类声明了一个授权任何 <T extends User>的方法。您的分机不符合此合同。

一些选项:

  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.
        }
    }
    
  3. 如果您使用后者,我强烈建议您额外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;
    }
    

    我还要注意,后者<T extends User>的方法与使用User相比没有任何好处,除非您要return User abstract class AbstractAuthorizer { abstract boolean supports(User user); abstract <T extends User> T authorize(T user); } 1}}如果获得授权。即,

    {{1}}