繁体   English   中英

Java抽象类获取扩展类的类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM