Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor in an Interface?

Tags:

java

interface

People also ask

Can you have a constructor in an interface?

No, you cannot have a constructor within an interface in Java. You can have only public, static, final variables and, public, abstract, methods as of Java7. From Java8 onwards interfaces allow default methods and static methods.

Why do we use constructor in interface?

The main purpose of the constructor is to initialize the newly created object. In abstract class, we have an instance variable, abstract methods, and non-abstract methods. We need to initialize the non-abstract methods and instance variables, therefore abstract classes have a constructor.


Taking some of the things you have described:

"So you could be sure that some fields in a class are defined for every implementation of this interface."

"If a define a Interface for this class so that I can have more classes which implement the message interface, I can only define the send method and not the constructor"

...these requirements are exactly what abstract classes are for.


A problem that you get when you allow constructors in interfaces comes from the possibility to implement several interfaces at the same time. When a class implements several interfaces that define different constructors, the class would have to implement several constructors, each one satisfying only one interface, but not the others. It will be impossible to construct an object that calls each of these constructors.

Or in code:

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

An interface defines a contract for an API, that is a set of methods that both implementer and user of the API agree upon. An interface does not have an instanced implementation, hence no constructor.

The use case you describe is akin to an abstract class in which the constructor calls a method of an abstract method which is implemented in an child class.

The inherent problem here is that while the base constructor is being executed, the child object is not constructed yet, and therfore in an unpredictable state.

To summarize: is it asking for trouble when you call overloaded methods from parent constructors, to quote mindprod:

In general you must avoid calling any non-final methods in a constructor. The problem is that instance initialisers / variable initialisation in the derived class is performed after the constructor of the base class.


A work around you can try is defining a getInstance() method in your interface so the implementer is aware of what parameters need to be handled. It isn't as solid as an abstract class, but it allows more flexibility as being an interface.

However this workaround does require you to use the getInstance() to instantiate all objects of this interface.

E.g.

public interface Module {
    Module getInstance(Receiver receiver);
}

There is only static fields in interface that dosen't need to initialized during object creation in subclass and the method of interface has to provide actual implementation in subclass .So there is no need of constructor in interface.

Second reason-during the object creation of subclass, the parent constructor is called .But if there will be more than one interface implemented then a conflict will occur during call of interface constructor as to which interface's constructor will call first


If you want to make sure that every implementation of the interface contains specific field, you simply need to add to your interface the getter for that field:

interface IMyMessage(){
    @NonNull String getReceiver();
}
  • it won't break encapsulation
  • it will let know to everyone who use your interface that the Receiver object has to be passed to the class in some way (either by constructor or by setter)

Dependencies that are not referenced in an interfaces methods should be regarded as implementation details, not something that the interface enforces. Of course there can be exceptions, but as a rule, you should define your interface as what the behavior is expected to be. Internal state of a given implementation shouldn't be a design concern of the interface.