繁体   English   中英

没有继承的Java代码重用

[英]Java code reuse without inheritance

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

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

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

我想在第三种方法中提取“公共代码”,如果我可以创建一个超类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();
}

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

使用界面

...如果我可以创建一个超级类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);
}

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

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

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

您可以使用静态方法

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();
}

您可以使用常用方法创建接口。

之后可以修改原始类来实现这些方法。

然后,您可以在函数中使用新创建的接口而不是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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM