Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有可能使两个Java接口相互排斥吗?_Java - Fatal编程技术网

有可能使两个Java接口相互排斥吗?

有可能使两个Java接口相互排斥吗?,java,Java,我有两个相互排斥的接口: interface Animal{} interface Cat extends Animal{} interface Bird extends Animal{} 如何防止同时实现Cat和Bird接口的类的实现 class Impossible implements Cat, Bird{} Java中的接口天生就是要实现的。任何类都可以实现任何接口,只要它愿意。因此,我认为没有办法防止这种情况。您可能需要重新考虑您的设计。Java没有提供阻止一个类实现两个不同接口的

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

interface Animal{}
interface Cat extends Animal{}
interface Bird extends Animal{}
如何防止同时实现
Cat
Bird
接口的类的实现

class Impossible implements Cat, Bird{}

Java中的接口天生就是要实现的。任何类都可以实现任何接口,只要它愿意。因此,我认为没有办法防止这种情况。您可能需要重新考虑您的设计。

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

对于动物来说,这似乎令人困惑,因为在现实生活中,没有一种动物同时是猫和狗。但是没有理由一个Java类不能同时满足
Cat
接口和
Dog
接口的契约。如果你想在现实中解决这个问题,考虑一个盒子里既有猫也有狗! 现在,正如Torben和其他人所指出的,您可以故意将方法引入一个接口中,这将与另一个接口中的方法发生冲突。这将导致Java禁止在一个类中实现两个接口。但是,由于上面列出的原因,这不是一个好的工作要考虑。p>
如果您必须强制建立这种关系,最好的方法是。

您可能无法阻止。也许你可以用一个抽象类来代替猫和鸟,不可能的事情只能扩展一个。

有一个非常非常难看的解决方法。对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 {
}

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

这里有一个清晰的层次结构-一个带有分支的根,一个节点(类、接口等)显然不能位于多个分支上。为了实现这一点,请使用抽象类而不是接口

当层次结构中的任何类都可以共享某些横切方面,并且没有两个接口是互斥的时,可以使用接口

例如:

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

至少有一个人考虑过这个问题:

当一个类要使用它时,你会抛出一个异常,UML图会这样做

正如您在上面看到的,
可能的
可以实现
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);
  }
}

不确定这是否有帮助,但如果不指定该接口为公共接口,则只有在与该接口相同的包中定义的类才能访问该接口


因此,基本上,您可以将接口放在一个包中,而不希望在另一个包中实现它的任何类。

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

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
public interface Animal{}
公共接口猫扩展动物{}
公共接口Bird扩展了Animal{}
公共类CatBird实现了Cat,Bird{}//编译器错误
公共接口CatBird扩展了Cat,Bird{}//编译器错误
CatBird无法实现,因为:



接口Animal不能用不同的参数实现多次:Animal和Animal

不确定这是否适合您的用例(我假设animals thing只是一个例子),但是您不能改为使用
Cat
Bird
抽象类吗?您不明白您的问题是什么吗?请你详细说明一下好吗?如果您不想提供接口的实现,请不要实现它。
//不要将此接口与Bird一起实现,因为……
尽管有几个答案的作者清楚地理解了这个问题,但这个问题已被搁置。此外,没有一名选民要求作出任何澄清。我认为这个问题不应该被搁置。我同意@Torben的观点,我已经投票决定重新讨论。这个问题对我来说很清楚,我不知道如何重新设计。请给出一个提示。正如其他人所示,有(好的和坏的)方法来防止它。实际上,如果程序员同时定义了两个接口,他就可以防止它。请看我的答案。@Torben Java的设计不是为了防止两个接口同时实现。当然,您已经发现了一个解决方法,但这并没有改变Java并不打算让您阻止这一事实。因此,我认为我的答案仍然有效,问题不是Java是否被设计为允许它。问题是这是否可能。即使事实证明你的答案是错误的,你也在为你的答案寻找理由。@Torben我编辑了我的问题,以反映我想表达的观点。我认为,重要的是要考虑java作为语言自然允许什么,因为每当你用工作来对付这种行为时,你就经常做错什么。你在自己的答案中也提出了同样的观点。这个答案是与OOD相关的最佳答案。让java不再是多病态的决定绝对是史诗般的。实际上,我们终止了OOD的advatage,因为逻辑不是很强大,我们需要一种在func rep prog(作为良好实践重新激活钩子模式)之前不需要的拨号编程;我们在这里做的是一个丑陋的黑客。我们不应该试图将其应用到实际设计中。最好保持黑客作为一个完全无用的方法,从来没有实际用于其他任何东西。并记录为什么JavaDocs中存在这种黑客行为。此外,不允许猫-鸟-动物取消不兼容等神话生物的资格是确保相互排斥的唯一途径。你说它丑陋,我说它优雅!即使一只变异的鸟不会长命百岁。。。。这应该是编译时的问题。对于一个
BirdCat
的家伙,你会有另一个i