私は例を落としますので、私は、どのようにこのフレーズにしないでください
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
その方法になることです
私がやるのであれば
final Account account = ...
final AccountAdmin admin = ...
final User user = ...
user.doSomething(account); // should work
user.doSomething(AccountAdmin); // should fail
Javaの8のとして、あなたは取るコンストラクタ定義することができSupplier
、適切なタイプの戻りインスタンスを。
あなたは言った:
私はこれで欲しいのはUserクラス内私はのgetType()を行うことができるということです、それはこの場合、アカウント内AbstractAccountの特定のタイプを返します。
そして、あなたがしたいです: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
最高の名ではありません)。