Java,可以修改抽象类层次结构中超类的方法声明吗?
我有一个抽象类Java,可以修改抽象类层次结构中超类的方法声明吗?,java,generics,abstract-class,abstract,class-hierarchy,Java,Generics,Abstract Class,Abstract,Class Hierarchy,我有一个抽象类UserdataUpdater,它扩展了Updater Updater有一个方法声明 public abstract void processRow (Cluster cluster, IAppendOnlyData row); 是否在UserdataUpdater中修改此方法声明以使其更具体,如 public abstract void processRow (Cluster cluster, IUserData row); IUserData扩展IAppendOnlyD
UserdataUpdater
,它扩展了Updater
Updater
有一个方法声明
public abstract void processRow (Cluster cluster, IAppendOnlyData row);
是否在UserdataUpdater
中修改此方法声明以使其更具体,如
public abstract void processRow (Cluster cluster, IUserData row);
IUserData
扩展IAppendOnlyData
,因为我希望扩展UserdataUpdater
的类只接受IUserData
不,您不能。这将打破超类的约定,即:此方法接受IAppendOnlyData作为第二个参数
请记住,子类的实例也是其超类的实例。因此,任何人都可以将子类实例引用为其超类,并调用base方法,传递IAppendOnlyData,而不知道该实例实际上是子类实例
请阅读更多有关该网站的信息
唯一的方法是使超类成为泛型:
public class Updater<T extends IAppendOnlyData> {
...
public abstract void processRow(Cluster cluster, T row);
}
public class UserdataUpdater extends Updater<IUserData> {
@Override
public void processRow(Cluster cluster, IUserData row) {
...
}
}
公共类更新程序{
...
公共抽象void processRow(Cluster Cluster,T row);
}
公共类UserdataUpdater扩展了更新程序{
@凌驾
public void processRow(群集、IUserData行){
...
}
}
不,你不能。这将打破超类的约定,即:此方法接受IAppendOnlyData作为第二个参数
请记住,子类的实例也是其超类的实例。因此,任何人都可以将子类实例引用为其超类,并调用base方法,传递IAppendOnlyData,而不知道该实例实际上是子类实例
请阅读更多有关该网站的信息
唯一的方法是使超类成为泛型:
public class Updater<T extends IAppendOnlyData> {
...
public abstract void processRow(Cluster cluster, T row);
}
public class UserdataUpdater extends Updater<IUserData> {
@Override
public void processRow(Cluster cluster, IUserData row) {
...
}
}
公共类更新程序{
...
公共抽象void processRow(Cluster Cluster,T row);
}
公共类UserdataUpdater扩展了更新程序{
@凌驾
public void processRow(群集、IUserData行){
...
}
}
不能修改派生类中的方法声明。如果派生类方法具有完全相同的方法签名,则只能重写超类方法。必须使用函数重载,并使用您提到的新参数类型创建新方法processRow
。不能修改派生类中的方法声明。如果派生类方法具有完全相同的方法签名,则只能重写超类方法。您必须使用函数重载,并使用您提到的新参数类型创建一个新方法processRow
。根据我的经验,您必须使用第一个声明,然后在实现中检查以确保:
row instanceof IUserData
当然,这是在运行时检查的,而不是在编译时检查的,但我不知道还有什么其他方法可以解决这个问题。当然,您也可以将行强制转换为类型IUserData,无论是盲目还是在检查其类型(如上所述)之后。根据我的经验,您必须使用第一个声明,然后在实现中检查以确保:
row instanceof IUserData
当然,这是在运行时检查的,而不是在编译时检查的,但我不知道还有什么其他方法可以解决这个问题。当然,您也可以将行强制转换为IUserData类型,不管是盲目还是在检查其类型(如上所述)之后
您可以创建这样一个函数,但由于签名不同,编译器会将其视为不同的函数
如果你想一想,你想做的事情就没有意义了。假设您编写了一个函数,该函数将更新程序作为参数,并使用非IUserData的内容对其调用processRow。在编译时,Java无法知道对象是否传入了Updater、UserdataUpdater或Updater的其他子类。那么,它是否应该允许通话?编译器应该做什么
您可以在UserdataUpdater.processRow内部执行操作,包括检查运行时传入的类型并引发异常的代码,或者在类型无效时执行其他类型的错误处理。简短回答:否
您可以创建这样一个函数,但由于签名不同,编译器会将其视为不同的函数
如果你想一想,你想做的事情就没有意义了。假设您编写了一个函数,该函数将更新程序作为参数,并使用非IUserData的内容对其调用processRow。在编译时,Java无法知道对象是否传入了Updater、UserdataUpdater或Updater的其他子类。那么,它是否应该允许通话?编译器应该做什么
您可以在UserdataUpdater.processRow内部执行操作,包括检查运行时传入的类型并引发异常的代码,或者在无效时执行其他类型的错误处理。假设您无法控制更新程序类,则无法执行此操作。。。您必须使用完全相同的签名实现该方法。但是,您可以在实现内部检查
行的类型
,并确定适当的处理方式:
public void processRow (Cluster cluster, IAppendOnlyData row)
{
if( row instanceof IUserData )
{
// your processing here
}
else
{
// Otherwise do whatever is appropriate.
}
}
假设你对Updater类没有控制权,你就不能这么做。。。您必须使用完全相同的签名实现该方法。但是,您可以在实现内部检查
行的类型
,并确定适当的处理方式:
public void processRow (Cluster cluster, IAppendOnlyData row)
{
if( row instanceof IUserData )
{
// your processing here
}
else
{
// Otherwise do whatever is appropriate.
}
}
你能重新措辞你的最后一句话吗?