【问题标题】:Child method from superclass (java)来自超类(java)的子方法
【发布时间】:2014-01-14 11:29:15
【问题描述】:

我有一个超类,比如说BaseClass和两个子类,比如说SubclassASubclassB,它们没有任何其他关系他们之间,但他们的父类。

在我的代码中的很多地方,我需要调用两个子类都具有但父类没有的方法......而且我发现自己重复了很多看起来像这样的代码:

if (obj instanceof SubclassA) {
// stuff
} else if (obj instanceof SubclassB) {
// same stuff
}

第一个想法应该是将“东西”放入超类中的方法中,但我不能因为该超类是其他没有这种行为的子类的父类...

那么...有没有办法避免重复所有代码?

也许两个子类的共同超类本身就是超类的子类?

【问题讨论】:

  • 这段代码在SuperClass里面吗?超类不知道子类

标签: java oop inheritance


【解决方案1】:

我建议将该方法提取为父类中的抽象方法(如果父类是抽象的),或者只是将在子类中覆盖的方法。如果这是不可能的,或者是不可取的,我建议添加一个通用抽象类来扩展父级,该父级仅具有两个子类共有的方法,然后由两个子类扩展。

如果添加和更改父类可能是一个问题,您可以通过使用由两个子类实现的接口来执行相同的操作,并且在您需要调用代码的地方,您只需转换到给定的接口并调用所需的方法。

类似这样的:

interface CommonInterface {
   void commonMethod();
}

class SubClassB implements CommonInterface {
    void commonMethod() {
        // implementation
    }
}

class SubClassA implements CommonInterface {
    void commonMethod() {
       // implementation
    }
}

//...
if (obj instanceof CommonInterface) {
   ((CommonInterface)object).stuffCall();
} 

【讨论】:

    【解决方案2】:

    将方法添加到超类。
    用一个空的身体来制作它。

    在 SubClassA 中覆盖它,实现你需要的逻辑。
    在 SubClassB 中覆盖它,实现你需要的逻辑。

    然后在你的调用代码中,而不是做

    if (obj instanceof SubclassA) {
        obj.method();
    } else if (obj instanceof SubclassB) {
        obj.method();
    }
    

    就这样做

    obj.method();
    

    如果obj被声明为父类的一个实例。

    超类中的空方法体保证你有
    这个没有问题“但是我不能因为那个超类是父类
    到其他没有这种行为的子类”

    所以想法是你会有空的行为
    在超类和所有子类中
    不要显式覆盖此方法。

    【讨论】:

      【解决方案3】:

      首先,多态性的概念是消除在调用对象方法之前检查对象类型的需要。因此,这在 OO 语言中不是必需的。

      其次,您可能会在接口上使用抽象父类的原因是因为子类型(子类)之间存在一些共享功能。因此,如果SubclassASubclassB 之间存在共享的通用功能,则保持超类不变,否则将其切换到接口。

      同样,正如您自己建议的那样,如果 SubclassASubclassB 具有共同的行为(但它们自己的实现),则使用单独的 API(如果 BaseClass 的其他子类型也不共享该行为(您的#doStuff 电话)。

      在这种情况下,我将引入包含方法#doStuff 的接口Stuff 并让我的SubclassASubclassB 实现它,每个都提供它自己的实现。然后,您的客户可以将您的 obj 实例视为 Stuff,而不管它的真实类型如何,剩下的事情将由多态性完成。

      interface Stuff {
          void doStuff();
      }
      
      public class SubclassA extends BaseClass implements Stuff {
          // Does it need BaseClass still?
          public doStuff() {
              ...
          } 
      }
      
      public class SubclassB extends BaseClass implements Stuff {
          // Does it need BaseClass still?
          public doStuff() {
              ...
          } 
      }
      
      // Example client code...
      public class MyStuffClient {
      
          Stuff s = new SubclassA();
          ...
          public void onStuff() {
              s.doStuff();
          } 
      }
      

      决定你是否真的需要 suer 类BaseClass

      【讨论】:

        【解决方案4】:

        以下两种方式呢:

        1. 在超类中声明目标方法并提供默认实现(例如空方法,什么也不做)。如果需要,子类将覆盖该行为。
        2. 在接口中声明目标方法,并实现接口的SubclassA和SubclassB。超类和其他子类不需要实现接口。

        【讨论】:

          【解决方案5】:

          如果 SubClassA 和 SubClassB 具有子类 C、D、E 等中不存在的某些行为,则只需在父类和 A 和 B 之间引入一个中间类。C、D 等从父类派生,B 从新类派生类,其中包含 A 和 B 共享的功能。

          【讨论】:

            【解决方案6】:

            您可以在超类protected 上创建该方法。例如,您可以在 SuperClass 上执行此操作:

            package test;
            public SuperClass {
               protected void myMethod() {
                  ...stuff...
               }
            }
            

            暴露在 SubclassA

            package test;
            public SubclassA extends SuperClass {
               public void myMethod() {
                  super.myMethod();
               }
            }
            

            并隐藏在 SubclassB 上(只是不要覆盖它)

            package test;
            public SubclassB extends SuperClass {
            }
            

            来自不同的包,受保护的方法是不可见的,除非类覆盖它并更改其可见性修饰符。

            来源:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

            【讨论】:

              猜你喜欢
              • 2019-06-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-08
              • 2011-11-14
              • 2012-04-08
              • 1970-01-01
              相关资源
              最近更新 更多