Как объединить два объекта в 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? Если да, то дайте мне знать, как я могу добиться этого?
7 ответов
в 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();
}
}
в некоторых языках поддерживается множественное наследование, которое может быть тем, что вы ищете здесь. Но не на Яве. Вы можете или не хотите сделать пару интерфейсов здесь, чтобы связать TestSet более тесно вместе с test01 и test02.
пожалуйста, дайте мне знать, если это возможно в Java?
это невозможно. Вы не можете динамически комбинировать такое поведение в Java.
нормальный способ совместить поведение в Java заключается в использовании некоторой комбинации наследования и wrappering или делегации. Даже тогда, там будет вопрос из подтипов ... если вы не используете интерфейсы ... поскольку Java не позволяет классу иметь несколько (direct) надклассы.
рассмотрим, например, @Panzercrisis по. В то время как его test03
класс реализует методы с теми же сигнатурами, что и test01
и test02
классы, экземпляр test03
тип не совместим ни с одним из них. (Вы не можете использовать test03
экземпляр как test01
или test02
. Java не поддерживает ввод утка!)
чтобы решить, что вам нужно будет определить интерфейсы face01
и face02
, которые реализуются test01
и test02
соответственно. Тогда вы бы реализовали test03
внедрение и face01
и face02
.
но это все статические классы и статической типизации.
при некоторых обстоятельствах вы можете использовать DynamicProxy
или что-то похожее на "синтез" класса, который "объединяет" поведение двух существующих классов. Однако все это делается со статическими типами и генерацией кода за кулисами. Более того, этот подход был бы жизнеспособным только в том случае, если бы вы предвидение, чтобы определить кучу интерфейсов (например,face01
и face02
) и напишите свой код приложения против интерфейсов, а не классов реализации.
вы можете определить класс Y в другом классе X как внутренний класс, и вы можете использовать класс Y в классе X. Кроме этого, поскольку я знаю, что это невозможно сделать.
короткий ответ, Нет, это невозможно, как вы описываете.
появление этого может быть возможно, если test01
и test02
где интерфейсы и у вас был третий класс 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();
}
}