是否可以在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){
}
}
不,你不能直接做你要求的事情。但是,您可以获得相同的效果。
当你做一些泛型的东西时,你是在向用户做出承诺:这将适用于任何满足泛型边界的类型。因此,通过在子类中选择特定类型,您就违反了该规则。但是,如果正确定义超类,则可以在满足类型检查器的同时获得所需的行为。不要使函数泛型,而是使类泛型,然后当你对它进行子类化时,你可以选择它所处理的类型。
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) {}
}
抽象类声明了一个将授权任何<T extends User>
的方法。 扩展不符合此合同。
一些选项:
-
泛化抽象类。
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. } }
-
让扩展执行必要的检查。 类似于(
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;
}
我还要指出,后者中带有<T extends User>
的方法与简单地使用User
没有任何好处,除非您要在授权的情况下return
User
。 即,
abstract class AbstractAuthorizer {
abstract boolean supports(User user);
abstract <T extends User> T authorize(T user);
}