继承:使用 base class 或 derived class 来做事情

Inheritance : using base class or derived class to do stuff

这是一个关于应该使用继承方式的简单问题。

考虑到我必须提供业务逻辑来打印 'foo' 和 'bar' 并且我有两个 classes 的层次结构:一个只有打印方法 'foo' 和另一个首先扩展并具有打印方法 'bar' 的方法。 在两个 classes 中,我都有一个名为 necessaryMethod() 的方法,它负责调用打印 'foo' 和 'bar' 的那些方法。

我用两种方法实现它的方式:

第一种方法是让基 class 做一些事情并派生 class 利用它。第二种方法是让 base class 不做任何事情(只提供实现)并将所有责任交给 derived class。

考虑以下代码:

方法一:

public class A{

    protected void necessaryMethod(){
        callFoo();
    }

    protected void callFoo(){
        System.out.pritln("foo");
    }       
}

public class B extends A{

    @Override
    protected void necessaryMethod(){
        super.necessaryMethod();
        callBar();
    }

    protected void callBar(){
        System.out.println("bar");
    }   
}

public class FooBarClass{
    public static void main(String args[]){
        B b = new B();
        b.necessaryMethod();
    }
}

方法二:

public abstract class A{

    protected abstract void necessaryMethod();

    protected void callFoo(){
        System.out.pritln("foo");
    }       
}

public class B extends A{

    @Override
    protected void necessaryMethod(){
        calFoo();
        callBar();
    }

    protected void callBar(){
        System.out.println("bar");
    }   
}

public class FooBarClass{
    public static void main(String args[]){
        B b = new B();
        b.necessaryMethod();
    }
}

哪种方法对代码的可维护性和可读性更好(在大型软件产品/大 class 层次结构的上下文中;这只是一个示例)?

(这是一道普通的编程题,我没有征求意见。)

如果您想使用派生的 classes 但将它们屏蔽为基础 classes,基础 class 应该具有派生的 class 的所有功能(因为你告诉对象 "think" 它是 A 而忘了它是 B)。所以在我看来最好的方法是:

public abstract class A{
   protected abstract void callBar();
   protected abstract void callFooBar();
   protected void callFoo() {
      System.out.pritln("foo");
   }
}

public class B extends A {
@Override
  protected void callBar(){
    System.out.println("bar")
  }
@Override
  protected void callFooBar(){
   callFoo();
   callBar();
  }
}

然后像这样将 B 称为 A:

A b = new B();
b.callFooBar();

我认为这是很容易维护的,因为一旦你创建了基础 class,你就可以非常灵活地处理派生的 classes 并且你总是比您的派生 class 与基础 class 相比。除非你涉足过度继承,这总是不好的。始终尝试只有 1 级继承,偶尔有两级。其他任何事情都会迅速失控,如果您需要那么多继承,那么评估接口是否不是更好的选择可能是个好主意。

暂时离开编程的技术方面,事物的行为方式(它的方法)有助于定义它。即狗叫声()。

一般问题是:

  1. 行为 callFoo() 是否让您想到 'A'(class A)或 'B'?

1.1。在 classes 中组织方法(行为),它们将属于编程之外 - 在定义 class.

大型代码库

尽管 B 在现实世界中可能属于 A 的集合,但有时过多的继承会不利于导航和维护代码。继承的目的更重要,实现继承本身和不使用继承的调用可能更好。

我在一年前实现了一个大型代码库,对其背后复杂的 UML 感到非常自豪,但是最近重新访问它是一场噩梦。在某些地方,我可以更谨慎地选择是否使用继承。

这里的问题是:这种继承是否有助于组织代码?它对其他程序员有帮助吗?

摘要类

在程序中的任何一点实例化超级 class 的实例来代替其中一个子 class 是否有意义?如果没有,那么抽象超级 class 获得投票。