简体   繁体   English

没有继承的Java代码重用

[英]Java code reuse without inheritance

I have 2 methods calling same method names: 我有2个方法调用相同的方法名称:

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

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

I would like to extract to "common code" in a third method, this would be possible if I could create a super class of Obj1 and Obj2 but I can't. 我想在第三种方法中提取“公共代码”,如果我可以创建一个超类Obj1Obj2 ,那么这是可能的,但我不能。 There is no way make these 2 objects inherit from a super class. 这两个对象无法从超类继承。 So my question is, is there a way in Java to do this kind of extraction when there is no link between objects, something like: 所以我的问题是,当对象之间没有链接时,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();
}

Yes, but it's ugly: Reflection. 是的,但它很难看:反思。 But before we get to that, let me push back on something in the question: 但在我们谈到之前,让我回过头来讨论一些问题:

Use an interface 使用界面

...this would be possible if I could create a super class of Obj1 and Obj2 but I can't. ...如果我可以创建一个超级类Obj1Obj2这是可能的,但我不能。 There is no way make these 2 objects inherit from a super class. 这两个对象无法从超类继承。

They don't have to: They can just implement the same interface, without inheriting from the same superclass: 他们不必:他们可以只实现相同的接口,而不继承同一个超类:

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

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

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

Then 然后

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

Use a wrapper 使用包装器

If for some reason you can't even add an interface, use a wrapper class (an adapter class) that implements the interface. 如果由于某种原因您甚至无法添加接口,请使用实现该接口的包装类( 适配器类)。

Use reflection 使用反射

In the worst case, you can use reflection: Use any of the several mechanisms on Class that let you find methods (such a getMethod ), and then use Method#invoke on that method: 在最坏的情况下,您可以使用反射:使用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);
}

That example is re-discovering the methods every time. 这个例子每次都会重新发现这些方法。 If you ran into a performance problem doing that, you might look at caching them. 如果遇到性能问题,可能会考虑缓存它们。

If the method body is the exactly the same, then they should inherit from a parent because they share a feature. 如果方法体完全相同,那么它们应该从父节点继承,因为它们共享一个特征。

Alternatively, you can create an interface to share a behavior between the classes. 或者,您可以创建一个界面来共享类之间的行为。 But this will require implementing the body of the interface in both classes implementing it 但这需要在实现它的两个类中实现接口的主体

You could use a static method 您可以使用静态方法

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

However, both object classes need to have a common interface NewObj in which case you can add this method to the interface: 但是,两个对象类都需要具有公共接口NewObj在这种情况下,您可以将此方法添加到接口:

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

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

You can create an interface with common methods. 您可以使用常用方法创建接口。

After you can modify the original classes to implements those methods. 之后可以修改原始类来实现这些方法。

Then you can use the new created interface instead of Object as parameter in the function. 然后,您可以在函数中使用新创建的接口而不是Object作为参数。

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

In the Obj1 , Obj2 classes you need only to implements DoOperations Obj1Obj2类中,您只需要实现DoOperations

public Obj1 implements DoOperations {
    ....
}

public Obj2 implements DoOperations {
    ....
}

To call it: 打电话给它:

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