构造函数在接口?

我知道在接口中定义一个构造函数是不可能的。 但我想知道为什么,因为我认为这可能是非常有用的。

所以你可以肯定,一个类中的一些字段是为这个接口的每个实现定义的。

例如,考虑以下消息类别:

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

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

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

“所以你可以肯定,一个类中的一些字段是为这个接口的每个实现定义的。”

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

…这些要求正是抽象类所要求的。

当你在接口中允许构造函数时,你会得到一个问题,因为它可能同时实现多个接口。 当一个类实现了几个定义不同构造函数的接口时,这个类将不得不实现几个构造函数,每个构造函数只能满足一个接口,而不能满足其他接口。 构build一个调用每个构造函数的对象是不可能的。

或者在代码中:

 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); } } 

一个接口定义了一个API的契约,这是API的实现者和用户同意的一组方法。 一个接口没有实例实现,因此没有构造函数。

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

这里固有的问题是,在基础构造函数被执行时,子对象还没有被构造,因此处于不可预知的状态。

总而言之,当你从父构造函数中调用重载方法时,是不是要问一下,引用mindprod :

一般来说,你必须避免在构造函数中调用任何非final方法。 问题是派生类中的实例初始化/variables初始化是在基类的构造函数之后执行的。

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

第二个原因 – 在子类的对象创build期间,调用父构造函数,但是如果实现了多个接口,那么在调用接口构造函数期间将发生冲突,以致哪个接口的构造函数将首先调用

在接口方法中没有引用的依赖关系应该被视为实现细节,而不是接口强制的东西。 当然,可能会有例外,但是作为一项规则,您应该将接口定义为行为预期的内容。 给定实现的内部状态不应该是接口的devise问题。

看到这个问题 为什么 (从评论采取)。

如果你真的需要这样做,你可能需要一个抽象的基类,而不是一个接口。

这是因为接口不允许在其中定义方法主体。但是我们必须定义与接口具有相同类的构造函数,所有要定义的方法都使用默认的抽象修饰符。 这就是为什么我们不能在接口中定义构造函数。

这是一个使用这个技术的例子。 在这个指定的示例中,代码使用模拟的MyCompletionListener调用Firebase,该模块是一个被屏蔽为抽象类的接口,带有构造函数的接口

 private interface Listener { void onComplete(databaseError, databaseReference); } public abstract class MyCompletionListener implements Listener{ String id; String name; public MyCompletionListener(String id, String name) { this.id = id; this.name = name; } } private void removeUserPresenceOnCurrentItem() { mFirebase.removeValue(child("some_key"), new MyCompletionListener(UUID.randomUUID().toString(), "removeUserPresenceOnCurrentItem") { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { } }); } } @Override public void removeValue(DatabaseReference ref, final MyCompletionListener var1) { CompletionListener cListener = new CompletionListener() { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { if (var1 != null){ System.out.println("Im back and my id is: " var1.is + " and my name is: " var1.name); var1.onComplete(databaseError, databaseReference); } } }; ref.removeValue(cListener); } 

如果你想确保接口的每个实现都包含特定的字段,你只需要在你的接口中添加这个字段的getter

 interface IMyMessage(){ @NonNull String getReceiver(); } 
  • 它不会破坏封装
  • 它会告诉每个使用你的接口的人, Receiver对象必须以某种方式传递给类(通过构造函数或setter方法)