使用相同方法签名实现多个接口

4

假设有接口 I1 和 I2

interface I1{int i=1; void foo();}

interface I2{int i=2; int foo();}

有没有办法让一个类A实现它们两个?我无法正确实现foo方法,这是有道理的,因为在I1.foo()和I2.foo()中具有相同的输入参数将不允许类A区分它们两个。

但常量"i"不是问题,只要您在尝试读取它们时将A转换为其中一个接口:

System.out.println(((I2)new A()).i);

看起来编译器说:“好吧,我会让你在'potentiality'存在歧义,但是当涉及到'actuality'时,我会阻止你”。而方法的“实际性”似乎更早出现。

我对吗?我有遗漏什么吗?还是我只是想象编译器像亚里士多德主义者一样与我交谈?


这可能会对你有所帮助:Java中接口实现中的方法名称冲突 - mdl
3个回答

4
如果您使用的是Java 8,可以尝试以下操作:
interface I1 {
  default void foo() {
    //some default implementation
  }
}

interface I2 {
  default int foo() {
    //some default implementation
  }
}

public class SomeClass implements I1, I2 {
  I2.super.foo();
}

4

不行。在Java中,您可以将接口视为契约。因为这些接口具有相同的方法名称(但返回类型不同),没有一个类可以满足两个契约。如果它们具有不同的参数,则答案将是肯定的。


那么字段“i”呢?它可以编译,但不允许创建类A的实例。 - Filipp Voronov
@Ph.Voronov 在一个接口中吗?它不是一个字段,而是一个常量。 - Elliott Frisch
是的,我说的是这些常量。"interface I1{int i=1;} interface I2{int i=2;} class A implements I1, I2 {}" 可以编译通过,但在实例化 A 时会出现编译错误。 - Filipp Voronov
你通常不会在实例上访问常量。此外,编译并不能保证正确性。 - Elliott Frisch
@Ph.Voronov 这并不完全正确。您可以实例化 A,但当尝试读取“i”作为“A”的成员变量的值时(从内部或外部A本身),会出现编译错误。 - Luigi Cortese

0
尝试满足“大量接口”的需求,可能更好地通过查找发现来解决。最大的优势是解耦依赖关系和动态发现。
(我知道这不是针对理论化的目标。)
class A {
    private Map<Class<?>, ?> capabilities;
    A() {
        capabilities.put(I1.class, new I1() {...});
        capabilities.put(I2.class, new I2() {...});
    }

    public <T> T lookup(Class<T> intf) {
        Object obj = capabilities.get(intf);
        if (obj == null) {
            throw new OperationNotSupportedException(
               "Interface not found: " + intf.getName());
        }
        return intf.cast(obj);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接