[英]Java multiple interfaces and reflection
我有一個叫做X的類,它實現了多個(例如3個)接口,分別稱為A,B和C。
我創建了另一個擴展接口A和B的接口AB。
如何使用反射創建可分配給接口AB的X實例?
我通過以下代碼不斷收到ClassCast異常:
package test.messages;
public interface A
{
void methodA();
}
package test.messages;
public interface B
{
void methodB();
}
package test.messages;
public interface C
{
void methodC();
}
package test.messages;
public interface AB extends A, B
{
}
package test.messages;
public class X implements A, B, C
{
@Override
public void methodC()
{
System.out.println("C");
}
@Override
public void methodB()
{
System.out.println("B");
}
@Override
public void methodA()
{
System.out.println("A");
}
}
然后在一個完全不同的類中:
AB api = (AB)Class.forName("test.messages.X").newInstance();
System.out.println(api);
現在,當我嘗試僅使用一個接口(例如A)時,它就可以正常工作。
無論如何,要使其與組合接口AB一起使用嗎?
is-a關系不能那樣工作。 AB
實現A
和B
以及X
實現A
和B
事實並不會使X
可分配給AB
。
即使您可能認為AB
與實現A
和B
任何類型都兼容,事實並非如此,因為AB
是另一種類型,並且Java中的層次結構樹由類本身的定義固定。
考慮一下Liskov替換原理 :如果將方法添加到AB
則X
不再是有效的候選者,因為它不包含AB
聲明的方法。
您將需要一種支持結構類型系統的編程語言。
您不能這樣做,因為在繼承樹中X並未實現AB。 如果A,B,C都是接口,則解決此問題的簡便方法是說X實現AB,C,這意味着它可以轉換為A,B,C和AB。
您真正想要的是AND類型 A&B
。 Java通常不支持此功能。 但是,我們可以創建一個包裝器類,其中包含一個值,該值既是類型A也是類型B。(似乎每個問題都可以通過包裝器解決:)
public class AB<T extends A&B>
{
public final T v;
...
v = (T)Class.forName("test.messages.X").newInstance();
}
除了使用A&B
類型之外,我們在需要的地方都使用AB<?>
。 我們將在其字段v
上進行操作,該字段既是A
也是B
void foo(AB<?> ab)
{
ab.v.methodOfA();
ab.v.methodOfB();
}
或者也可以將AB
設為A和B的子類型。
public class AB<T extends A&B> implements A, B
{
public final T v;
@Override // A
public int methodOfA(){ return v.methodOfA(); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.