如果两个类有一些完全相同签名的方法,但这些方法没有被继承,有没有办法用常用方法定义接口,并使用相同的接口指向两个类的两个实例?
例如,假设某个班级Cat
有boolean isAlive()
而另一个班级Dog
有boolean isAlive()
,但Cat
和Dog
没有共同的祖先除Object
和boolean isAlive()
之外的其他方法不是继承方法。我无法修改Cat
或Dog
,因为它们是由其他人编写的。我可以随意创建这样的界面并用它来指向猫或狗吗?
interface lovable
{
boolean isAlive();
}
void main()
{
lovable thing = new Cat(); <-- any syntax to achieve this?
love(thing);
}
void love(lovable thing)
{
if (thing.isAlive())
System.out.println("Aww.");
else
System.out.println("Eww.");
}
答案 0 :(得分:4)
如果您自己创建:
public interface Lovable{
boolean isAlive();
}
public class LovableCat extends Cat implements Lovable{
}
public static void main() {
Lovable thing = new LovableCat();
love(thing);
}
如果从其他地方返回:
public interface Lovable{
boolean isAlive();
}
public class LovableCat implements Lovable{
private Cat cat;
public LovableCat(Cat cat){
this.cat = cat;
}
public boolean isAlive(){
return cat.isAlive();
}
}
public static void main() {
Lovable thing = new LovableCat(cat);
love(thing);
}
答案 1 :(得分:1)
您可以像Can you force a java object into implementing an interface at runtime?中提到的那样创建代理对象:
public interface Loveable {
boolean isAlive();
}
public static class Cat {
boolean isAlive() {
return true;
}
}
public static class Dog {
boolean isAlive() {
return false;
}
}
public static <T> T getWrapper(final Object obj, final Class<T> intface) {
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return obj.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()).invoke(obj, args);
}
};
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), new Class[]{intface}, invocationHandler);
}
public static void main(String[] args) throws Exception {
System.out.println(getWrapper(new Cat(), Loveable.class).isAlive());
System.out.println(getWrapper(new Dog(), Loveable.class).isAlive());
}
答案 2 :(得分:0)
你不能因为你的类型(Cat,Dog)必须实现你的界面。如果这个类来自某些lib,你有多少2个解决方案。第一个使用包装器如上所述,第二个使用反射。我认为lib www.eclipse.org/aspectj可以帮助你以最小的方式实现它。