繁体   English   中英

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

[英]Is it possible to make two Java interfaces mutually exclusive?

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

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

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

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 {
}

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

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

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

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

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

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

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

如果你必须强迫这种关系,最好的方法是NickJ提供的答案

当一个类要使用它时,你会抛出异常,UML Diagram会喜欢这个
在此输入图像描述
正如你在上面看到的那样, 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);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM