Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无继承的Java代码重用_Java - Fatal编程技术网

无继承的Java代码重用

无继承的Java代码重用,java,Java,我有两个方法调用相同的方法名: public void doSomething1(Obj1 obj1) { obj1.do1(); obj1.do2(); obj1.do3(); } public void doSomething2(Obj2 obj2) { obj2.do1(); obj2.do2(); obj2.do3(); } 我想在第三种方法中提取到“公共代码”,如果我能创建一个Obj1和Obj2的超类,这是可能的,但我不能。无法使这两

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

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

public void doSomething2(Obj2 obj2) {
    obj2.do1();
    obj2.do2();
    obj2.do3();
}
我想在第三种方法中提取到“公共代码”,如果我能创建一个
Obj1
Obj2
的超类,这是可能的,但我不能。无法使这两个对象从超类继承。 所以我的问题是,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();
}

是的,但它很丑陋:反射。但在我们讨论这个问题之前,让我回顾一下问题:

使用接口 …如果我可以创建
Obj1
Obj2
的超类,这将是可能的,但我不能。无法使这两个对象从超类继承

它们不必这样做:它们只需实现相同的接口,而无需从相同的超类继承:

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

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

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

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

使用反射 在最坏的情况下,您可以使用反射:使用
上的几种机制中的任何一种,让您找到方法(例如),然后在该方法上使用:

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

如果方法体完全相同,则它们应该从父级继承,因为它们共享一个特征


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

您可以使用通用方法创建接口

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

然后,您可以使用新创建的接口而不是对象作为函数中的参数

public interface DoOperations {
    void do1();
    void do2();
    void do3();
}
Obj1
Obj2
类中,您只需要实现
o操作

public Obj1 implements DoOperations {
    ....
}

public Obj2 implements DoOperations {
    ....
}
称之为:

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

如果
do1()
方法是相同的方法,而不仅仅是两个名称相同的方法,则可以使用“static”方法执行此操作。是否可以使这两个方法都从
接口继承?
?不,我无法编辑它们,它们是存根生成的类ESOBJ1和Obj2不可编辑,它们是生成的classes@Ferdossi:这就留下了包装器或反射,如果生成它们的任何东西都没有添加接口定义的可配置性(这是令人惊讶的)。它们是单独生成的,是完全不同的一部分jars@Ferdossi当前位置它们是否在不同的罐子中并不重要(考虑一下:任何时候你从JDK实现一个接口,你都是从另一个jar实现一个接口),如果它们是单独生成的,这并不重要。但是,如果你不能做到上面的1,你仍然有2和3。
public void doSomething(DoOperations obj) {
    obj.do1();
    obj.do2();
    obj.do3();
}