没有继承的Java代码重用

时间:2016-09-21 13:34:29

标签: java

我有2个方法调用相同的方法名称:

public void doSomething1(Obj1 obj1) {
    obj1.do1();
    obj1.do2();
    obj1.do3();
}

public void doSomething2(Obj2 obj2) {
    obj2.do1();
    obj2.do2();
    obj2.do3();
}

我想提取到#34;常用代码"在第三种方法中,如果我可以创建一个Obj1Obj2的超类,那么这是可能的,但我无法做到。这两个对象无法从超类继承。 所以我的问题是,当对象之间没有链接时,Java是否有办法进行这种提取,如:

public void doSomething1(Obj1 obj1) {
    refactor(obj1);
}

public void doSomething1(Obj2 obj2) {
    refactor(obj2);
}

private void refactor(NewObj newObj) {
    newObj.do1();
    newObj.do2();
    newObj.do3();
}

4 个答案:

答案 0 :(得分:6)

是的,但它很难看:反思。但在我们谈到之前,让我回过头来讨论问题:

使用界面

  

...如果我可以创建一个Obj1Obj2的超级课程,这是可能的,但我无法做到。这两个对象无法从超类继承。

他们不必:他们可以实现相同的接口,而不必继承同一个超类:

public interface TheCommonInterface {
    void do1();
    void do2();
    void do3();
}

public class Obj1 implements TheCommonInterface {
    // ...
}

public class Obj2 implements TheCommonInterface {
    // ...
}

然后

private void refactor(TheCommonInterface obj) {
    obj.do1();
    obj.do2();
    obj.do3();
}

使用包装器

如果由于某种原因您甚至无法添加接口,请使用实现该接口的包装类(适配器类)。

使用反射

在最坏的情况下,您可以使用反射:使用Class上的任何一种机制来查找方法(例如getMethod),然后使用Method#invoke方法:

public void refactor(Object obj) {
    Class cls = obj.getClass();
    cls.getMethod("do1").invoke(obj);
    cls.getMethod("do2").invoke(obj);
    cls.getMethod("do3").invoke(obj);
}

这个例子每次都会重新发现这些方法。如果遇到性能问题,可能会考虑缓存它们。

答案 1 :(得分:3)

如果方法体完全相同,那么它们应该从父节点继承,因为它们共享一个特征。

或者,您可以创建一个界面来共享类之间的行为。但这需要在实现它的两个类中实现接口的主体

答案 2 :(得分:2)

您可以使用静态方法

private static void refactor(NewObj newObj) {
    newObj.do1();
    newObj.do2();
    newObj.do3();
}

但是,两个对象类都需要有一个公共接口NewObj,在这种情况下,您可以将此方法添加到接口:

interface NewObj {
    default void do123() {
        do1();
        do2();
        do3();
    }

    void do1();
    void do2();
    void do3();
}

答案 3 :(得分:1)

您可以使用常用方法创建界面。

您可以修改原始类以实现这些方法。

然后您可以在函数中使用新创建的接口而不是Object作为参数。

public interface DoOperations {
    void do1();
    void do2();
    void do3();
}

Obj1Obj2课程中,您只需要实施DoOperations

public Obj1 implements DoOperations {
    ....
}

public Obj2 implements DoOperations {
    ....
}

要打电话:

public void doSomething(DoOperations obj) {
    obj.do1();
    obj.do2();
    obj.do3();
}