我有两个界面,它们应该互斥:
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
canFly
是一个状态。flying=true
或 flying=false
可能是一些有 canFly
能力的事物的可能状态,因此 canFly
可能指定方法 takeOff()
和 land()
。 - NickJsetFlying(boolean)
。 - Grim有一个非常非常丑陋的解决方法。实现与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
和Bird
,这样“不可能”只能继承一个。
不确定这是否有帮助,但如果您没有指定接口为公共接口,则该接口只能被定义在与接口相同的包中的类访问。
因此,您可以将接口放在一个包中,任何您不想实现它的类都可以放在另一个包中。
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);
}
}
interface BirdCat implements Animal{}
。 - user2511414Java没有提供一种语法来防止一个类实现两个不同的接口。这是一件好事,因为接口应该让你忘记你正在处理哪个对象,只关注与该接口相关的功能。
在动物的情况下,这可能会令人感到困惑,因为在现实生活中,没有动物既是猫又是狗。但是,一个Java类可以履行Cat
接口和Dog
接口的契约,这没有任何问题。如果您想将其落实到现实中,请考虑一个包含猫和狗的盒子!
现在,正如Torben和其他人指出的那样,您可以故意将方法引入接口中,这些方法将与其他接口中的方法冲突。这将导致Java禁止在一个类中实现两个接口。但是,基于上述原因,这不是一个好的解决方法。
如果您必须强制执行此关系,则最好的方法是NickJ提供的答案。
Cat
和Bird
变成抽象类吗? - tobias_k// Do not implement this interface together with Bird, because...
- zch