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.
    }
}

你能重新措辞你的最后一句话吗?