Java 如何从两个类中提取共性。。模板法?

Java 如何从两个类中提取共性。。模板法?,java,oop,Java,Oop,我有两节课 public class ABC { public void test() { Car a = new Car(); a.start(); } } public class DEF { public void test() { Car a = new Car(); a.start(); a.stop(); } } 现在这两个类做的事情基本相同,如何提取共性,或者最好的方法是什么。

我有两节课

public class ABC {
    public void test() {
       Car a = new Car();
       a.start();
    }
}

public class DEF {
    public void test() {
       Car a = new Car();
       a.start();
       a.stop();
    }
}

现在这两个类做的事情基本相同,如何提取共性,或者最好的方法是什么。。模板方法有效吗。。在这里,我使用一个接口。。。并且有一个父方法调用在子类上实现的抽象方法?。。。但这意味着一个类在一个方法中有一个no操作?

好的,所以这些方法有一些共同点:

Car a = new Car();
a.start();
您可以做的是创建一个抽象类,这两个类都可以扩展

public abstract class ParentClass
{
      public void test()
      {
              Car a = new Car();
              a.start();
      }
}
然后从子类中调用:
super.test()。这将在返回到当前方法并完成子类实现之前调用父类中的方法

这种方法的优点

现在可以拉出这些类中的任何通用代码,并将其放入父类中。这意味着没有代码重复,这总是好的。这还意味着,如果适当地提供了超类函数,则类具有逻辑结构。这同样被认为是良好的实践,因为它使您的代码在语义上更符合逻辑

这种方法的缺点


ParentClass
是其他类可以扩展的唯一类。这就是所谓的多重继承,Java不支持多重继承,所以请记住这一点。如果您的
ABC
也与另一组类共享类似的功能,那么您可能需要重新考虑您的类结构。

是的,您可以在此处使用模板方法模式:

public abstract class Template {

    public void test() {
       Car a = new Car();
       a.start();
       if(shouldStop()) {
           a.stop();
       }
    }

    public abstract boolean shouldStop();

}

public class ABC extends Template {

    public boolean shouldStop() {
        return false;
    }

}

public class DEF extends Template {

    public boolean shouldStop() {
        return true;
    }

}

这里您添加了一个钩子,允许子类在需要时停止。显然,您可以将其扩展到包括任何其他可选功能。

除了这个简单的示例之外,我还需要考虑其他功能,但您可以这样做:

public class ABC {
    public Car test() {
       Car a = new Car();
       a.start();
       return a;
    }

}

public class DEF extends ABC {
    public Car test() {
       Car a = super.test();
       a.stop();
    }
}

当您有所有子类都应该共享的步骤时,模板方法是有用的

基本结构是你已经说过的。包含一些必须由子类实现的抽象方法的抽象类


另一方面,接口定义的是API,而不是行为。因此,在这种情况下,它是无用的。

通常,并且尽可能多地,我更喜欢将公共功能放在外部(和静态)方法中,主要是因为两个原因(它们有非常细微的区别和关联):

  • 我宁愿避免保留我的“继承槽”,我可以只从一个类继承,我希望在扩展时贪婪,在非常必要或适当的情况下使用它(参见第2点)

  • 继承应该只在类之间存在“类型”关系的情况下使用;无论如何,我个人认为,在Java中,在某些情况下,您可能会被迫以错误的方式使用继承,因为Java语言不提供共享公共功能(例如ruby中的模块)的机制