3

我有多个接口和一个实现所有接口的类。我想在实现类的实例上调用这些接口中定义的所有方法,但我不想将变量声明为类类型,以便我仍在对接口进行编程。

看来我必须:

  1. 将对象从一种接口类型转换为另一种接口类型以调用适当的方法。
  2. 创建一个扩展其他接口的联合接口并声明该类型的变量。

我宁愿不这样做,因为 1 不是类型安全的,而 2 可能意味着您很快就会得到很多“联合”接口,它们本身什么都不添加。是否有可能有类似的东西:

public interface A {
    public void doThis();
}

public interface B {
    public void doThat();
}

public class C implements A, B {
    public void doThis(){;}
    public void doThat(){;}
}


//Fake calling code:
public void go() {
    A,B dualTypedInstance = new C(); //
    dualTypedInstance.doThis();
    dualTypedInstance.doThat();

}

看起来这真的应该是可能的。谢谢。

4

6 回答 6

2

你可以这样做:

ImplementsInterfaces impl = new ImplementsInterfaces();
A a = impl;
B b = impl;
于 2013-04-13T09:03:17.240 回答
1

在 2019 年做到这一点并非完全不可能,尽管我不一定会在生产代码中推荐该解决方案,并且它还带有一个警告,即对象必须是不可变的。例如,要创建一个有效地具有实现 InterfaceA 和 InterfaceB 的实例变量的类,它们分别具有方法 methodA() 和 methodB(),您可以执行以下操作

public interface MyInterface {
  public void methodA();
  public void methodB();

  public static <O extends InterfaceA & InterfaceB> MyInterface of(O obj){
      return new MyInterface(){
          public void methodA(){
               obj.methodA();
          }

          public void methodB(){
               obj.methodB();
          }
      };
  }

这将创建一个匿名内部类,它实际上具有类型为 InterfaceA 和 InterfaceB 的最终实例变量,而无需对该依赖项的任何特定实现。

于 2019-11-29T00:53:44.867 回答
0

为什么不想实例化实现 (a) 和 (b) 的类 (c)?

另一种方法是从 (a) 和 (b) 创建抽象类,并有两个抽象方法(每个都有一个,就像你已经拥有的那样),然后创建类 (c),然后扩展(而不是实现)其他类。

于 2013-04-13T08:58:19.967 回答
0

一种替代方法是创建抽象超类:

public abstract class AbstractAB implements A, B {
}

public class C extends AbstractAB {
    public void doThis(){;}
    public void doThat(){;}

}

public void go() {
    AbstractAB dualTypedInstance = new C();
    dualTypedInstance.doThis();
    dualTypedInstance.doThat();
}
于 2013-04-13T09:09:16.483 回答
0

您也可以在 Class 声明中执行此操作:

public class<T extends A & B> SomeClass{
     Void doStuff(){
          T variable = new C();
     }
}
于 2020-09-21T16:14:23.177 回答
-1

接口应该包含一个独特的抽象单元,以便它们可以单独使用,即不知道它们的实现并且不依赖于可能在一个类中实现的其他接口。接口可以扩展其他接口,但层次结构本身并不是一个东西,它应该在您的应用程序中具有某种意义。因此,如果您被迫制作许多人为的“标记”界面,那么您做错事的可能性非常高。最后但同样重要的是,您可以拥有一个可以实现必要接口的抽象基类。

让我用一个简单的例子来说明这一点。假设您正在为应用程序创建前端。您可以考虑可以拖动或实现的不同面板。用 java 术语来说,可以有两个接口:Draggablewith a drag()method 和Resizablewith redize()method。在拖动事件下,您的 API 不应该知道实现类的详细信息,它唯一应该关心的是,这个类是否实现Draggable。但是如果您希望有一个具体的实现,它的两个接口都以可能不同的方式实现,您可以创建一个抽象类作为具体实现的基础:abstract class BasePanel extends Panel implements Draggable, Resizable. 这样,您以一种可以在单独的“拖动”广告“调整大小”上下文中的方式声明您的类。另一方面,如果您想拥有一个能够同时了解它们的上下文,您可以创建另一个接口来扩展基本接口,并可能添加另一个方法,例如public interface GuiUnit extends Draggable, Resizable.

最后,我的想法是向您展示,当您期望在不相关的接口之间进行条件转换时,您应该避免设计情况,并且要么将您的实现完全基于您希望处理的一个接口,要么基于一组抽象类。如果你认为这还不够——你最好重新考虑你的设计考虑。

于 2013-04-13T09:32:03.513 回答