避免在类上重复代码

时间:2018-08-12 23:04:15

标签: java

我正在编写一些类,并且所有这些类都实现了它们从接口继承的特定方法。除了调用某个其他函数之外,所有类的方法都几乎相同。

例如:

public void doSomething(){
    int a = 6;
    int b = 7;
    int c = anOtherMethod(a,b);
    while(c < 50){
        c++;
    }
}

如果多个类具有doSomething()函数,但方法anOtherMethod()的实现不同怎么办?

在这种情况下如何避免代码重复? (这不是我的实际代码,而是简化的版本,可以帮助我更好地描述我的意思。)

3 个答案:

答案 0 :(得分:5)

这似乎是template method pattern的一个很好的例子。

  1. doSomething放在基类中。
  2. 也可以在该基类中声明abstract protected anotherMethod,但不提供实现。
  3. 然后,每个子类为anotherMethod提供适当的实现。

答案 1 :(得分:4)

这是实现以下示例中Thilo讨论的技术的方式:

主类:

public class Main extends Method {

    public static void main(String[] args) {
        Method m = new Main();
        m.doSomething();
    }

    @Override
    public int anOtherMethod(int a, int b) {
        return a + b;
    }
}

抽象类:

public abstract class Method {

    public abstract int anOtherMethod(int a, int b);

    public void doSomething() {
        int a = 6;
        int b = 7;
        int c = anOtherMethod(a, b);

        System.out.println("Output: "+c);
    }
}

这样,您要做的就是在要使用anOtherMethod()的每个类中使用方法doSomething()的不同实现重写anOtherMethod()

答案 2 :(得分:3)

假设anOtherFunction的每个版本都使用两个整数并返回一个整数,我只是让该方法接受一个函数作为参数,使其具有更高的阶数。

接受两个相同类型参数并返回相同类型对象的函数称为BinaryOperator。您可以在方法中添加该类型的参数以在以下位置传递函数:

// Give the method an operator argument 
public void doSomething(BinaryOperator<Integer> otherMethod) {
    int a = 6;
    int b = 7;

    // Then use it here basically like before
    // "apply" is needed to call the passed function
    int c = otherMethod.apply(a,b);
    while(c < 50) 
        c++;
    }
}

不过,如何使用取决于您的用例。作为使用lambda的简单示例,您现在可以像这样调用它:

doSomething((a, b) -> a + b);

仅返回ab的和。

但是对于您的特定情况,您可能会发现doSomething作为接口的一部分不是必需的,也不是最佳的。相反,如果需要提供anOtherMethod,该怎么办?与其期望您的班级提供doSomething,不如让他们提供BinaryOperator<Integer>。然后,当您需要从doSomething获取结果时,请从该类中获取运算符,然后将其传递给doSomething。像这样:

public callDoSomething(HasOperator obj) {
    // There may be a better way than having a "HasOperator" interface
    // This is just an example though
    BinaryOperator<Integer> f = obj.getOperator();

    doSomething(f);
}