【问题标题】:Overriding an instance method with static ones用静态方法覆盖实例方法
【发布时间】:2011-01-04 03:33:18
【问题描述】:

我有一个将被子类化的类。所有子类都必须包含具有相同签名但每个子类不同的静态方法。

我想在子类将覆盖的超类中有一个抽象实例方法,但在 Java 中似乎不可能,我想知道为什么。

一个愚蠢的例子:

  • 图片{ 抽象字符串 getExtension();...

  • RGBImage 扩展图像{ 静态字符串 getExtension(){return "RGB"};..

  • PNGImage 扩展图像{ static String getExtension(){return "PNG"};...

【问题讨论】:

标签: java methods overriding


【解决方案1】:

看看这个explanation。您可以根据自己的目的使用 Builder 模式。

【讨论】:

    【解决方案2】:

    正如其他人所说,Java 不支持覆盖或 abstract 用于静态方法。但是,无论如何,我真的不明白你会用“抽象”静态方法实现什么。

    抽象方法的正常使用是强制每个子类实现具有相同签名的方法。但是,为什么对于静态(因此是非多态的)方法来说这很重要呢?如果您忘记为其中一个子类提供方法,要么没关系,因为你不调用它,要么没关系,但在尝试调用缺少的方法时会出现编译错误。

    我能想到的唯一用例是,如果您以伪多态方式反射性地调用该方法。但是如果你这样做,你最好使用真正的多态性和实例方法。

    【讨论】:

      【解决方案3】:

      我不会做太多 Java,但是(使用 C++ 逻辑)您可以使基类实现成为无法执行的虚拟实现。

      static void DoStuff(arg_type arg)
      {
          std::cerr << "Method DoStuff() must be overriden\n";
          ::abort();
      }
      

      这不如抽象方法好,但它会达到一些相同的结果。

      【讨论】:

        【解决方案4】:

        不幸的是,这在 Java 中是不可能的。您必须使它们能够定义为抽象的实例方法。

        【讨论】:

          【解决方案5】:

          不能覆盖静态方法,因为它们属于类,而不是实例。

          此外,实例方法不能像您在示例中建议的那样在子类中设为静态。

          您能否提供更多信息,说明为什么所有子类都需要具有相同的静态方法?

          【讨论】:

            【解决方案6】:

            你想用静态方法覆盖实例方法吗?这是没有意义的。静态方法不是多态的。你想怎么称呼它?在 Java 中,强制类具有给定签名的静态方法是不可能的。

            【讨论】:

              【解决方案7】:

              正如其他人所说,静态不是多态的......这意味着它对于类是相同的,而不是特定于实例。我不确定你会通过使用静态方法来完成什么......但你可以让你的扩展方法实现返回一个静态值:

              public String getExtension() {
                return STATIC_CONSTANT;
              }
              

              我想这取决于您尝试使用静态方法完成的工作。从您的帖子中:“让我说,在每个子类中实现实例 getExtension() 方法一切正常。但关键是该方法实际上在子类中是静态的,不依赖于实例。我知道我可以'不要那样做,我只是说这对我来说似乎没有什么奇怪的想法。”

              问题是您从定义类而不是实例的行为的东西中要求多态行为(每个子类的方法行为的变化)。根据定义,静态不能是多态的。我希望这可以帮助您理解为什么这是不可能的。

              【讨论】:

                【解决方案8】:

                我想要在超类中声明抽象方法的原因是因为该类必须对抽象方法的结果做一些额外的工作。

                让我们简单地说,即使示例没有意义:

                Image{
                
                abstract String getExtension();
                
                int process(){
                
                   return getExtension().length
                
                }
                

                process() 中的算法对于Image 的所有子类XXXImage 都是通用的,所以它的正确位置是超类。

                让我说,在每个子类中实现实例 getExtension() 方法一切正常。但关键是该方法实际上在子类中是静态的,不依赖于实例。

                我知道我做不到,我只是说这对我来说似乎没有什么奇怪的想法。

                【讨论】:

                  【解决方案9】:

                  是的,这就是我正在做的,重新调整静态常量。在可能的情况下,它返回一个内部枚举的类对象,该对象列出了给定文件格式的部分的名称:子类的文件格式。

                  但是你在你的例子中说得很清楚:

                  公共字符串 getExtension() {

                  返回静态常量;

                  }

                  我希望能够在 String 之前添加“静态”...

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-10-06
                    • 2012-07-19
                    • 2018-06-21
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多