Rob*_*ich 42 java generics inheritance
我有一个抽象类Monitor.java,它由Class EmailMonitor.java子类化.
方法:
public abstract List<? extends MonitorAccount> performMonitor(List<? extends MonitorAccount> accounts)
Run Code Online (Sandbox Code Playgroud)
在Monitor.java中定义,必须在EmailMonitor.java中重写.
我目前在EmailMonitor.java中重写了如下方法:
@Override
public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {
//...unrelated logic
return emailAccounts;
}
Run Code Online (Sandbox Code Playgroud)
但是,这会产生编译时错误:
Name clash: The method performMonitor(List<EmailAccount>) of type EmailMonitor has the same erasure as performMonitor(Lis<? extends MonitorAccount> emailAccounts) of type Monitor but does not override it
EmailAccount
是一个子类MonitorAccount
,所以(至少在我看来)以这种方式覆盖它是完全有道理的.虽然编译器对我的逻辑不满意,但是如何在保持编译时检查以确保所有调用EmailMonitor.performMonitor()
接收列表EmailAccount
而不是其他类型的MonitorAccount
?
Jon*_*eet 34
不,它没有正确地覆盖它.覆盖意味着您应该能够处理基类的任何有效输入.考虑如果客户端这样做会发生什么:
Monitor x = new EmailMonitor();
List<NonEmailAccount> nonEmailAccounts = ...;
x.performMonitor(nonEmailAccounts);
Run Code Online (Sandbox Code Playgroud)
根据你的描述,那里没有什么应该给出编译时错误 - 但这显然是错误的.
听起来我觉得Monitor
它可以监控的帐户类型应该是通用的,所以你EmailMonitor
应该扩展Monitor<EmailAccount>
.所以:
public abtract class Monitor<T extends MonitorAccount>
{
...
public abstract List<? extends T> performMonitor(
List<? extends T> accounts);
}
public class EmailMonitor extends Monitor<EmailAccount>
{
@Override
public abstract List<? extends EmailAccount> performMonitor(
List<? extends EmailAccount> accounts)
{
// Code goes here
}
}
Run Code Online (Sandbox Code Playgroud)
您可能想要仔细考虑performMonitor
电话中的泛型- 返回值意味着什么?
这是我自己的解决方案.我怀疑这与Jon Skeet试图解决的问题是一样的......没有错字(请参阅我对回答的评论).
在Monitor.java类:
public abstract class Monitor <T extends MonitorAccount> {
...
public abstract List<T> performMonitor(List<T> accounts);
..
}
Run Code Online (Sandbox Code Playgroud)
EmailMonitor.java
public class EmailMonitor extends Monitor<EmailAccount> {
...
public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {
..//logic...logic...logic
return emailAccounts;
}
...
}
Run Code Online (Sandbox Code Playgroud)
在这个配置中,EmailMonitor.performMonitor()将始终在编译时检查它收到的EmailAccount列表而不是我的其他任何类型的FTPAccount,DBAccount等...它比替代方案更清晰,它本来就是接收/发送原始列表,然后必须强制它所需的类型,从而导致潜在的运行时类型转换异常.