Java,我可以将任意接口应用于现有类吗?

时间:2016-02-26 15:43:52

标签: java interface

如果两个类有一些完全相同签名的方法,但这些方法没有被继承,有没有办法用常用方法定义接口,并使用相同的接口指向两个类的两个实例?

例如,假设某个班级Catboolean isAlive()而另一个班级Dogboolean isAlive(),但CatDog没有共同的祖先除Objectboolean isAlive()之外的其他方法不是继承方法。我无法修改CatDog,因为它们是由其他人编写的。我可以随意创建这样的界面并用它来指向猫或狗吗?

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

3 个答案:

答案 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可以帮助你以最小的方式实现它。