簡體   English   中英

如何在Java中組合兩個對象?

[英]How do I combine two objects in Java?

考慮:

public class test01{

    public void doSomething(){
        // do something
    }

}

public class test02{

    public void printSomething(){
        // print something
    }

} 

// in main
test01 t1 = new test01();
test02 t2 = new test02();

// I want do to something like this
test01 t3 = t1.merge(t2);

// with t3 I should be able to access both t1 and t2 functions
t3.doSomething();
t3.printSomething();

如果可以在Java中使用,請告訴我? 如果是,那么讓我知道如何實現這一目標?

java中沒有多重繼承。 你可以做的是使test02的子類test01然后創建test03作為的子類test02

要么

你可以把它們組成一個像這樣的Test03類:

public class Test03 {

    private Test01 test01;
    private Test02 test02;

    public void doSomething() {
        test01.doSomething();
    }

    public void printSomething() {
        test02.printSomething();
    }

}

請注意 ,在java中,您不應該使用像test01這樣的類名。 它們應該是有意義的並且符合java類命名准則。

你最好的選擇可能就是:

public class TestSet {
    private test01 t1 = new test01();
    private test02 t2 = new test02();

    public void doSomething() {
        t1.doSomething();
    }

    public void printSomething() {
        t2.printSomething();
    }
}

在某些語言中,支持多重繼承,這可能是您在這里尋找的。 但不是用Java。 您可能想要也可能不想在這里創建幾個接口,以便將TestSet與test01和test02更緊密地結合在一起。

如果可以在Java中使用,請告訴我?

這不可能。 您無法像Java中那樣動態組合行為。

在Java中組合行為的常規方法是使用繼承和包裝或委派的某種組合。 即使這樣,也會出現子類型的問題......除非你使用接口......因為Java不允許類有多個(直接)超類。

考慮@ Panzercrisis的例子。 雖然他的test03類實現具有相同簽名的方法test01test02類的一個實例test03不是類型與其中任何兼容。 (您不能將test03實例用作test01test02不支持duck typing!)

為了解決這個問題,您需要分別定義由test01test02實現的接口face01face02 然后,你將實現test03為實現 face01face02

但這是所有靜態類和靜態類型。


在某些情況下,您可以使用DynamicProxy或類似的東西來“合成”一個“合並”兩個現有類的行為的類。 但是,這些都是在幕后使用靜態類型和代碼生成完成的。 而且,這種方法只有在你有遠見來定義一堆接口(例如face01face02 )並根據接口而不是實現類編寫應用程序代碼時才可行。

你可以在另一個類X中將類Y定義為內部類,並且可以在類X中使用類Y.除此之外,我知道沒有辦法做到這一點。

簡短的回答,不,你不可能如何描述。

如果test01test02接口和你有第三類test03實現這兩者,那么這樣做的外觀可能是可能的。 在C ++中,這可以通過多重繼承來完成,但是它的功能大致相同(即你必須創建第三個類,而不是擴展它們),而且無論如何這個選項在Java中都不可用。

另一種選擇是@Panzercrisis描述的某種組合。

最后的選擇(我能想到的)是test02擴展test01但是改變了test02

但一般來說,不,不可能。

不,你不能,真正按照你描述的方式做到這一點,你可以做到

公共類test01擴展test02 {....

}

所以你的test1,你可以使用這兩個類中的方法,但是如果你真的想要將這些類合並在一起,你可以像這樣做一些令人厭惡的事:

public class MyObject {
    Map<String, Object> objects = new HashMap<String, Object>();
    Map<String, Method> methods = new HashMap<String, Method>();

    public Object execute(String methodAName)
{

    Object object = objects.get(methodAName);
    Method method = methods.get(methodAName);
    if (object==null || method==null)
    {
        throw new RuntimeException("method not found");
    }

    try {
        return method.invoke(object, null);
    } catch (Exception e) {
        throw new RuntimeException(e);

    }
}

    public void merge(Object o) {
        for (Method m : o.getClass().getMethods()) {
            objects.put(m.getName(), o);
            methods.put(m.getName(), m);
        }
    }
}

當你可以這樣使用它

 MyObject o = new MyObject();
 o.merge(new test01());
 o.merge(new test02());

 o.execute("printSomething");
 o.execute("doSomething");

但正如我所說,不推薦

你可以使用Java inheritance做類似的事情,但不是一回事。 你可以在這里使用extends 但是你必須確保方法覆蓋不會發生,否則你的要求不匹配。

Test02 extends Test01

然后

Test03 extends Test02 

現在你可以實現類似的東西了。

Test03 test=new Test03();

test.callMethodInTest1();
test.callMethodInTest2(); 

樣品:

public class Test1 {

public String callMethodInTest1() {
    return "test1";
  }
}

public class Test2 extends Test1{

public String callMethodInTest2() {
    return "test2";
  }
}

public class Test03 extends Test2 {

public static void main(String[] args){
   Test03 sample=new Test03();
   sample.callMethodInTest1();
   sample.callMethodInTest2();
 }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM