是否可以使两个Java接口互斥?

时间:2013-10-25 09:09:01

标签: java

我有两个互相排斥的接口:

interface Animal{}
interface Cat extends Animal{}
interface Bird extends Animal{}

如何阻止实现同时实现CatBird接口的类?

class Impossible implements Cat, Bird{}

8 个答案:

答案 0 :(得分:10)

最后一个肮脏的解决方案:

public interface Animal<BEING extends Animal> {}
public interface Cat extends Animal<Cat> {}
public interface Bird extends Animal<Bird> {}
public class CatBird implements Cat, Bird {} // compiler error
public interface CatBird extends Cat, Bird {} // compiler error

CatBird无法实施,因为:

接口Animal不能使用不同的参数多次实现:Animal&lt; Bird&gt;和动物&lt; Cat&gt;

答案 1 :(得分:8)

这里有一个清晰的层次结构 - 一个带分支的根,显然一个节点(类,接口,等等)不能在多个分支上。为了强制执行此操作,请使用抽象类而不是接口。

当存在某些交叉方面时,可以使用接口,这些方面可以在层次结构中的任何类之间共享,并且没有两个接口是互斥的。

示例:

public abstract class Animal;
public interface CanFly;
public interface CanHunt;
public abstract class Cat extends Animal implements CanHunt;
public abstract class Bird extends Animal implements CanFly;
public class Vulture extends Bird implements CanHunt; //also CanFly because of Bird

至少有一个人考虑过这个问题:http://instantbadger.blogspot.co.uk/2006/10/mutually-exclusive-interfaces.html

答案 2 :(得分:3)

Java中的接口很快就会实现。任何类都可以实现任何接口,只要它想要。所以,我认为没有办法阻止这种情况。您可能需要重新考虑您的设计。

答案 3 :(得分:3)

有一个非常非常丑陋的解决方法。为Cat和Bird接口实现冲突的方法签名:

public interface Cat {
    int x();
}

public interface Bird {
    float x();
}

/**
 * ERROR! Can not implement Cat and Bird because signatures for method x() differ!
 */
public class Impossible implements Cat, Bird {
}

但不要这样做。找出一个更好的方法。

答案 4 :(得分:2)

可能你无法阻止。也许你可以用抽象类替换CatBird,而Impossible只能扩展一个。

答案 5 :(得分:1)

不确定这是否有帮助,但是如果您没有指定接口是公共的,那么只有与接口在同一个包中定义的类才能访问您的接口。

基本上,您可以将您的界面放在一个包中,以及任何您不希望在另一个包中实现它的类。

答案 6 :(得分:0)

Java没有提供一种语法来阻止一个类实现两个不同的接口。这是一件好事,因为接口应该让你忘记你正在处理的对象,并专注于与该接口相关的功能。

在动物的情况下,这似乎令人困惑,因为在现实生活中,没有动物是猫和狗。但是没有理由认为一个Java类不能满足Cat接口和Dog接口的约定。如果你想在现实中解决这个问题,可以考虑一个包含猫和狗的盒子!

现在,正如Torben和其他人指出的那样,你可以故意将方法引入到与其他接口中的方法冲突的接口中。这将导致Java禁止在一个类中实现两个接口。但由于上面列出的原因,这不是一个好的解决方案。

如果你必须强制建立这种关系,最好的方法是answer provided by NickJ

答案 7 :(得分:0)

当一个类要使用它时,你会抛出异常,UML Diagram会喜欢这个 enter image description here
如上所述,Possible会实现CatBird,但不能同时实现。interface Animal{void x();} interface Cat extends Animal{} interface Bird extends Animal{} class Impossible implements Cat, Bird{ @Override public void x() { System.out.println("Oops!"); }} class Possible implements Cat{ @Override public void x() { System.out.println("Blah blah"); } } class Core { private Animal a; public void setAnimal(Animal a) throws Exception { if (a instanceof Cat && a instanceof Bird) { System.out.println("Impossible!"); throw new Exception("We do not accept magic"); } this.a = a; a.x(); } public static void main(String[] args) throws Exception { Core c = new Core(); Possible p = new Possible(); c.setAnimal(p); Impossible ip = new Impossible(); c.setAnimal(ip); } } 或{{1}}。但这只是一个图表,所以功能就是这样。

{{1}}