接口中的构造函数?

139 java interface

我知道在接口中定义构造函数是不可能的.但我想知道为什么,因为我觉得它可能非常有用.

因此,您可以确保为此接口的每个实现定义了类中的某些字段.

例如,考虑以下消息类:

public class MyMessage {

   public MyMessage(String receiver) {
      this.receiver = receiver;
   }

   private String receiver;

   public void send() {
      //some implementation for sending the mssage to the receiver
   }
}
Run Code Online (Sandbox Code Playgroud)

如果为这个类定义一个接口,以便我可以有更多的类来实现消息接口,那么我只能定义send方法而不是构造函数.那么我怎样才能确保这个类的每个实现都有一个接收器集呢?如果我使用像setReceiver(String receiver)我这样的方法,我不能确定这个方法是否真的被调用.在构造函数中,我可以确保它.

mat*_*t b 124

采取你所描述的一些事情:

"因此,您可以确定类中的某些字段是为此接口的每个实现定义的."

"如果为这个类定义一个接口,以便我可以有更多的类来实现消息接口,那么我只能定义send方法而不是构造函数"

......这些要求正是抽象类的用途.

  • Matt,这显然是正确的,但是抽象类受到单继承限制的影响,这导致人们看到指定层次结构的其他方式. (40认同)
  • 这是事实,可以解决Sebi的直接问题.但是在Java中使用接口的一个原因是因为你不能有多重继承.在我不能将我的"东西"变成抽象类的情况下,因为我需要继承其他东西,问题依然存在.不是说我声称有解决方案. (6认同)
  • @CPerkins虽然这是真的,但我并不是说简单地使用抽象类就能解决Sebi的用例.如果有的话,最好声明一个定义`send()`方法的`Message`接口,如果Sebi希望为`Message`接口的实现提供一个"基类",那么也提供一个`AbstractMessage`. .抽象类不应该取代接口,从不试图这样做. (6认同)
  • 明白了,马特。我没有和你争论,更多的是指出它不是操作想要什么的*完整*替代品。 (2认同)

dan*_*ann 74

在接口中允许构造函数时遇到的问题来自于同时实现多个接口的可能性.当一个类实现了几个定义不同构造函数的接口时,该类必须实现几个构造函数,每个构造函数只满足一个接口,而不满足其他接口.构造一个调用每个构造函数的对象是不可能的.

或者在代码中:

interface Named { Named(String name); }
interface HasList { HasList(List list); }

class A implements Named, HasList {

  /** implements Named constructor.
   * This constructor should not be used from outside, 
   * because List parameter is missing
   */
  public A(String name)  { 
    ...
  }

  /** implements HasList constructor.
   * This constructor should not be used from outside, 
   * because String parameter is missing
   */
  public A(List list) {
    ...
  }

  /** This is the constructor that we would actually 
   * need to satisfy both interfaces at the same time
   */ 
  public A(String name, List list) {
    this(name);
    // the next line is illegal; you can only call one other super constructor
    this(list); 
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果允许,“接口中的构造函数”最有用的含义是如果可以将 `new Set<Fnord>()` 解释为“给我一些我可以用作 `Set<Fnord>` 的东西”;如果`Set<T>` 的作者打算将`HashSet<T>` 作为没有特别需要的东西的首选实现,那么接口可以定义`new Set<Fnord>( )` 可以被认为是 `new HashSet<Fnord>()` 的同义词。一个类实现多个接口不会造成任何问题,因为`new InterfaceName()` 只会构造一个*由接口*指定的类。 (2认同)

rsp*_*rsp 13

接口定义API的合同,API是API的实现者和用户都同意的一组方法.接口没有实例化实现,因此没有构造函数.

您描述的用例类似于一个抽象类,其中构造函数调用在子类中实现的抽象方法的方法.

这里固有的问题是,在执行基础构造函数时,子对象尚未构造,因此处于不可预测的状态.

总结一下:当你从父构造函数调用重载方法时,它是否会引发麻烦,引用mindprod:

通常,您必须避免在构造函数中调用任何非final方法.问题是派生类中的实例初始化器/变量初始化是在基类的构造函数之后执行 的.


Pau*_*aul 6

您可以尝试的解决方法是定义一个 getInstance()方法是在您的接口中方法,以便实现者知道需要处理哪些参数。它不像抽象类那样可靠,但它作为接口具有更大的灵活性。

但是,此解决方法确实需要您使用getInstance()来实例化此接口的所有对象。

例如

public interface Module {
    Module getInstance(Receiver receiver);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

接口中只有静态字段,在子类中创建对象时不需要初始化,并且接口方法必须在子类中提供实际的实现。因此,接口中不需要构造函数。

第二个原因-在创建子类的对象期间,将调用父构造函数。但是,如果实现了多个接口,则在调用接口构造函数期间会发生冲突,即首先调用哪个接口的构造函数