我有两个应该相互排除的接口:
interface Animal{}
interface Cat extends Animal{}
interface Bird extends Animal{}
如何防止实现同时实现Cat
和Bird
接口的类的实现?
class Impossible implements Cat, Bird{}
我有两个应该相互排除的接口:
interface Animal{}
interface Cat extends Animal{}
interface Bird extends Animal{}
如何防止实现同时实现Cat
和Bird
接口的类的实现?
class Impossible implements Cat, Bird{}
最后一个肮脏的解决方案:
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<Bird> 和 Animal<Cat>
在这里,您有一个清晰的层次结构 - 一个带有分支的根,并且显然一个节点(类、接口等)不能位于多个分支上。为了强制执行这一点,请使用抽象类而不是接口。
当层次结构中的任何类之间可以共享某些横切方面,并且没有两个接口相互排斥时,可以使用接口。
例子:
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
Java 中的接口是为实现而生的。任何类都可以实现任何接口,只要它愿意。所以,我认为没有办法阻止这种情况。您可能需要重新考虑您的设计。
有一个非常非常丑陋的解决方法。对 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 {
}
但不要这样做。想出一个更好的方法。
可能你无法阻止。也许您可以用一个抽象类替换Cat
and Bird
,而 Impossible 只能扩展一个。
不确定这是否有帮助,但如果您没有指定接口是公共的,那么您的接口将只能被定义在与接口相同的包中的类访问。
所以本质上,你可以把你的接口放在一个包中,而你不想在另一个包中实现它的任何类..
Java 没有提供阻止一个类实现两个不同接口的语法。这是一件好事,因为接口应该让您忘记您正在处理的确切对象,而只关注与该接口相关的功能。
就动物而言,这似乎令人困惑,因为在现实生活中,没有任何动物既是猫又是狗。但是没有理由一个 Java 类不能同时履行Cat
接口和Dog
接口的契约。如果您想在现实中实现这一点,请考虑一个包含猫和狗的盒子!
现在,正如 Torben 和其他人所指出的,您可以故意将方法引入一个接口,这将与另一个接口中的方法发生冲突。这将导致 Java 禁止在一个类中实现两个接口。但是由于上面列出的原因,这不是一个很好的解决方法。
如果您必须强制这种关系,最好的方法是NickJ 提供的答案。
当一个类要使用它时,很多人会抛出一个异常,UML 图就像
你在上面看到的那样,Possible
将实现一个Cat
或Bird
,但不能同时实现两者。但这只是一个图表,所以功能应该是这样的。
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);
}
}