【问题标题】:Is it bad practice to override a function only to add a little bit of functionality by calling super?重写一个函数只是为了通过调用 super 添加一点功能是不好的做法吗?
【发布时间】:2017-01-30 14:26:09
【问题描述】:

如果我有一个超类 BaseClass 和一个子类 SubClass,并且我希望子类的某些功能稍有不同,那么只覆盖原来的、调用 super 并添加一些额外功能是不是不好的做法?

例如:(伪代码)

public class BaseClass{
   int fooA();
   int fooB();
   int fooC();
}

public class SubClass extends BaseClass{
   @Override
   int fooB(){
      int temp = super.fooB();
      temp += 1;
      return temp;
   }

   @Override
   int fooC(){
      System.out.println("I'm doing something extra in fooC!");
      return super.fooC();
   }
}

我试图防止代码重复,但我觉得我做错了什么或忘记了一些基本的 OOP 内容,所以我想我会问这是否是不好的做法。自从我做继承以来已经有一段时间了;感谢您的任何见解。

【问题讨论】:

  • 组合优于继承。
  • @Kayaman 您不能只说“更喜欢组合而不是继承”,就像它总是正确的那样。在某些情况下,组合比继承更合适,而在其他情况下,继承比组合更合适。
  • 我已经有一段时间没有做继承了。 :)
  • @MickaëlB 当然可以,我刚刚做到了。 prefer 这个词本身就包含了您提到的所有其他注意事项。

标签: java inheritance overriding subclass


【解决方案1】:

您可以执行以下操作,而不是继承:

public class SubClass implements MyInterface {
   private MyInterfaceBasicImpl base;

   int fooB(){
      int temp = base.fooB();
      temp += 1;
      return temp;
   }

   int fooC(){
      System.out.println("I'm doing something using in fooC in base object!");
      return base.fooC();
   }
}

这是Composition 模式的一个简单示例。由于Java 中没有多重继承,它会让您的代码保持开放以进行改进。

【讨论】:

  • 如果我希望 SubClass 具有与基类相似(或相同)的构造函数,我必须继承它,对吗? (我知道我没有把它放在我原来的问题中,但是当我查看我的代码时,出现了警告)。如果我没记错的话,我应该选择抽象类和接口的组合。感谢您的复习。
  • 在新的构造函数中,你可以构造你保留引用的对象。
【解决方案2】:

子类重写方法的能力允许类 从行为“足够接近”的超类继承,然后 根据需要修改行为。覆盖方法具有相同的名称, 参数的数量和类型,返回类型作为它的方法 覆盖。覆盖方法也可以返回该类型的子类型 由重写的方法返回。这种子类型称为协变 返回类型。

希望这可以回答您的问题。

https://docs.oracle.com/javase/tutorial/java/IandI/override.html

【讨论】:

    【解决方案3】:

    你可以按照你的建议去做,是一种选择。但是,如果你有 3 个类做同样的事情,会发生什么?您仍在重复代码和逻辑,因为在它们中的每一个中您都将调用 super。在这种情况下,您可以做的是实现模板方法模式。如果您还没有阅读过它,这意味着将超类中的方法定义为抽象,在那里使用它,然后在子类中定义它。按照您的示例,它可能看起来像这样:

    public class BaseClass{
       int fooA();
       int fooB();
       int fooC(){
         //here goes the common logic;
         this.printWhatItHasToPrint();
       }
       void printWhatItHasToPrint() {}; //if the class is abstract you may define it as abstract
    }
    
    public class SubClass1 extends BaseClass{
       @Override
       int fooB(){
          int temp = super.fooB();
          temp += 1;
          return temp;
       }
    
       @Override
       void printWhatItHasToPrint(){
            System.out.println("I'm doing something extra in fooC!");
       }
    }
    
    public class SubClass2 extends BaseClass{
    
       @Override
       void printWhatItHasToPrint(){
            System.out.println("I'm doing something extra in fooC, and I'm another class!");
       }
    }
    

    【讨论】:

      【解决方案4】:

      我认为这可能是正确的方法,但根据我的经验,创建一个具有通用功能的抽象类,然后有两个子类来扩展它以实现不同的功能,这样更易​​读和方便:

      public abstract class BaseClass {
          public void fooA() {
              System.out.println("Some common function");
          }
      
          public void fooB() {
              System.out.println("Another common function");
          }
      
          public abstract int fooC();
      }  
      
      public class SubClass1 extends BaseClass {
          @Override
          public int fooC() {
              return 0;
          }
      } 
      
      public class SubClass1 extends BaseClass {
          @Override
          public int fooC() {
              return 1;
          }
      }
      

      这样可以更轻松地浏览大型项目,感觉更自然

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        相关资源
        最近更新 更多