简体   繁体   中英

How do I combine two objects in Java?

Consider:

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

Please let me know if this is possible in Java? If yes, then let me know how can I achieve this?

There is no multiple inheritance in java. What you can do is making test02 a subclass of test01 then create test03 as a subclass of test02 .

OR

you can compose them into a Test03 class like this:

public class Test03 {

    private Test01 test01;
    private Test02 test02;

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

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

}

Please note that in java you shouldn't use class names like test01 . They should be meaningful and comform to the java class naming guidelines.

Your best option is probably this:

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

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

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

In some languages, multiple inheritance is supported, which may be what you're looking for here. But not in Java. You may or may not want to make a couple of interfaces here to tie TestSet more closely together with test01 and test02.

Please let me know if this is possible in Java?

It is not possible. You cannot combine behaviour dynamically like that in Java.

The normal way to combine behaviour in Java is to use some combination of inheritance and wrappering or delegation. Even then, there will be an issue of subtyping ... unless you use interfaces ... because Java does not allow a class to have multiple (direct) superclasses.

Consider for @Panzercrisis's example. While his test03 class implements methods with the same signatures as the test01 and test02 classes, an instance of test03 is not type compatible with either of them. (You can't use a test03 instance as a test01 or a test02 . Java doesn't support duck typing!)

To address that you would need to define interfaces face01 and face02 that are implemented by test01 and test02 respectively. Then you would implement test03 as implementing both face01 and face02 .

But this is all static classes and static typing.


Under some circumstances, you could use DynamicProxy or something similar to "synthesize" a class that "merges" the behaviour of two existing classes. However, that is all done with static types and code generation behind the scenes. Moreover, this approach would only viable if you'd had the foresight to define a bunch of interfaces (eg face01 and face02 ) and write your application code against the interfaces rather than the implementation classes.

你可以在另一个类X中将类Y定义为内部类,并且可以在类X中使用类Y.除此之外,我知道没有办法做到这一点。

Short answer, no it's not possible how you describe.

The appearance of doing this might be possible if test01 and test02 where interfaces and you had a third class test03 implement both. In C++ this would be done by multiple inheritance but that would function much the same way (ie you would have to create a third class that instead extends both) and this option isn't available in Java anyway.

Another option would be some sort of composition such as @Panzercrisis describes.

The final option (I can think of) would be to have test02 extend test01 but that alters test02 .

But generally, no, not possible.

No you can't, really do this in way how you describe this, you can do

public class test01 extend test02{ ....

}

so your test1, you can use methods from both classes, but if you can really whant yo play with merging classes together, you can do some abomination like this one:

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

and when you can use it like that

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

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

but as i said, not recommended

You can do something similar using Java inheritance , But not the same thing. you can use extends here. But you have to make sure method overriding not happen else your requirement not match.

Test02 extends Test01

Then

Test03 extends Test02 

Now you can achieve some thing similar.

Test03 test=new Test03();

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

Sample:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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