Search code examples
javaoopinterfacemultiple-inheritance

How to create an Interface that extends two other Interfaces to define type in java


I have two interfaces Inquiry and Validatable and I also have two classes ErrorReport and FunctionQuery implements Inquiry and Validatable both.

What is the best choice when I have a logic that uses a combination of two interfaces' operation? I know that I can separate it into two logic using Inquiry and Validatable, but the logic is combined so If I separate it, it makes other duplication.

I tried like below, but, I realized this hierarchy is not appropriate because Validatable is not a generalization of Inquiry in my application.

approach at first

public interface Inquiry extends Validatable {
  ...
}

and classes like this.

public class ErrorReport implements Inquiry{
  ...
}
public class FunctionQuery implements Inquiry {
  ...
}

new approach

So I create an interface like below.

public interface ValidatableInquiry extends Inquiry,Validatable{
  ...
}

and classes

public class ErrorReport implements ValidatableInquiry {
  ...
}
public class FunctionQuery implements ValidatableInquiry {
  ...
}

I think the new approach is better than the first, but I can't be assured. Is it the right approach? and Is there a better alternative?


Solution

  • To a certain degree, this is opinionated. Both solutions "work" for a smaller project of limited life time.

    But then it is very clear that the first solution carries one significant constraint: it introduces coupling between Inquiry and Validatable.

    Thus the answer is: if you are really sure about your "model", and the abstractions that you want to create ... in the sense of: yes, absolutely, any Inquiry will always be a Validatable, too, then that solution is okay. Because your code matches your mental model, and you are sure about the validity of your mental model.

    But if there is the slightest doubt that these two interface are actually independent of each other, then you should pick the 2nd approach. Because that approach says: the two interfaces are independent, and classes that need both functionalities can extend from that joining interface that brings the functionalities together.