【问题标题】:Java, Possible to modify method declaration of super class in abstract class hierarchy?Java,可以在抽象类层次结构中修改超类的方法声明吗?
【发布时间】:2012-10-08 20:10:09
【问题描述】:

我有一个抽象类UserdataUpdater,它扩展了Updater

Updater 有一个方法声明

 public abstract void processRow (Cluster cluster, IAppendOnlyData row);

有没有办法修改UserdataUpdater里面的这个方法声明,让它更具体,比如

 public abstract void processRow (Cluster cluster, IUserData row);

IUserData 扩展 IAppendOnlyData,因为我希望扩展 UserdataUpdater 的类只接受 IUserData

【问题讨论】:

  • 你能改写你最后一句话吗?

标签: java generics abstract-class abstract class-hierarchy


【解决方案1】:

不,你不能。这会破坏超类的约定,即:此方法接受 IAppendOnlyData 作为第二个参数。

请记住,子类的实例也是其超类的实例。所以任何人都可以将子类实例称为它的超类,并调用基方法,传递一个 IAppendOnlyData,而不知道该实例实际上是一个子类实例。

阅读更多关于Liskov substitution principle的信息。

做到这一点的唯一方法是使超类泛型:

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

【讨论】:

    【解决方案2】:

    您不能修改派生类中的方法声明。如果派生类方法具有完全相同的方法签名,则只能覆盖超类方法。您必须使用函数重载并使用您提到的新参数类型创建一个新方法processRow

    【讨论】:

      【解决方案3】:

      根据我的经验,您必须使用第一个声明,然后在实现中检查以确保:

      row instanceof IUserData
      

      当然,这是在运行时而不是在编译期间检查的,但我不知道有任何其他方法。当然,您也可以只将行转换为 IUserData 类型,无论是盲目地还是在检查其类型后(上图)。

      【讨论】:

        【解决方案4】:

        简短回答:不。

        你可以创建这样的函数,但是由于签名不同,编译器会将其视为不同的函数。

        如果你仔细想想,你正在尝试做的事情并没有真正的意义。假设您编写了一个函数,该函数将 Updater 作为参数并使用不是 IUserData 的内容调用 processRow。在编译时,Java 无法知道传递的对象是 Updater、UserdataUpdater 还是其他 Updater 的子类。那么它是否应该允许通话?编译器应该怎么做?

        您可以在 UserdataUpdater.processRow 中包含检查在运行时传入的类型并抛出异常或在其无效时进行其他类型的错误处理的代码。

        【讨论】:

          【解决方案5】:

          假设您无法控制 Updater 类,则不能这样做……您必须使用完全相同的签名来实现该方法。但是,您可以在您的实现中检查 row 的类型并决定适当的处理:

          public void processRow (Cluster cluster, IAppendOnlyData row)
          {
              if( row instanceof IUserData )
              {
                  // your processing here
              }
              else
              {
                  // Otherwise do whatever is appropriate.
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-04-03
            • 1970-01-01
            • 2016-12-09
            相关资源
            最近更新 更多