簡體   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