[英]Java abstract class to get type of extended class
我不知道怎么说这个,所以我会举一个例子
class AbstractUser<A extends AbstractAccount<? extends AbstractType>> {
// I want a method that has access to Type
// And returns the specific Type that extends AbstractType
protected <T extends AbstractType> T doSomething(T type) {
// do stuff
// and return the type specific type T
}
}
class AbstractAccount<T extends AbstractType> {
}
class AbstractType {
}
class Type extends AbstractType {
}
class Account extends AbstractAccount<Type> {
}
class AccountAdmin extends AbstractAccount<Type> {
}
class User extends AbstractUser<Account> {
}
我想要的是在User
类中我可以执行getType()
并返回特定类型的AbstractAccount
,在本例中为Account
。
如何在不指定任何模板的情况下执行此操作? 换句话说,我想要什么类型的?
在? extends AbstractType
? extends AbstractType
是在那个方法中
所以,如果我这样做
final Account account = ...
final AccountAdmin admin = ...
final User user = ...
user.doSomething(account); // should work
user.doSomething(AccountAdmin); // should fail
您显然无法在AbstractUser
创建方法,如下所示:
public Class<A> getType() { return A.class; }
这是因为类型擦除。 运行时不知道A
是什么。
所以一个解决方法是使这个方法抽象:
public abstract Class<A> getType();
现在,您可以在子类中实现此方法:
class User extends AbstractUser<Account> {
public Class<Account> getType() { return Account.class; }
}
编辑:
现在我意识到你想要扩展AbstractType
的类型,解决方法应该仍然有效。 您只需要在AbstractAccount
创建另一个getType
,并使Account
实现该方法。
为此,您无法真正绕过在AbstractUser
绑定另一个类型参数:
class AbstractUser<T extends AbstractType, A extends AbstractAccount<T>> {
protected abstract T getType();
}
您需要一种方法来引用A类型参数的类型,这就是为此目的。
从Java 8开始,您可以定义一个构造函数,该构造函数使Supplier
返回相应类型的实例。
你说:
我想要的是在User类中我可以执行getType()并返回特定类型的AbstractAccount,在本例中为Account。
你想要: doSomething(T type)
。
因此,我假设您不希望使用Class<T>
而是使用T
的实例。 在你的例子中,这个T
应该是Account
。
根据这个:
class AbstractUser<T extends AbstractType, A extends AbstractAccount<T>> {
private Supplier<T> accountSupplier;
public AbstractUser(Supplier<T> accountSupplier) {
this.accountSupplier = accountSupplier;
}
protected T getType() {
return accountSupplier.get();
}
}
然后类User
将如下所示:
class User extends AbstractUser<Type, Account> {
public User() {
super(Account::new);
}
}
请注意, AbstractUser
类仍未声明为abstract
。 如果让这个类的唯一原因是通过子类提供不同类型的AbstractAccount
,那么现在我们可以在没有子类的情况下完成它。
User user = new User();
可以重写为AbstractUser user = new AbstractUser(Type::new);
(在这种情况下, AbstractUser
不是最好的名字) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.