5

My first question is, is the Liskov principle applied even on constructor declaration?

I mean there, am I forced to have exactly the same number / types of parameter in my constructor for each (different) class?

Looking at this:

package com.apptest.test;

public class Application {

    public static void main(String[] args) {
        IRepository r = new RepositoryUser("toto");
        IRepository x = new BillingRepository("billing","super");

    }

}

We can see that there are two implementations of IRepository, but one uses one more parameter.

Is this correct, and can I tell that the Liskov principle is respected ?

gnat
  • 21,442
  • 29
  • 112
  • 288
Thomas thomas
  • 385
  • 1
  • 3
  • 8
  • 1
    Does this answer your question? [Where does the Liskov Substitution Principle generally lie in different constructor parameter lists?](https://softwareengineering.stackexchange.com/questions/270734/where-does-the-liskov-substitution-principle-generally-lie-in-different-construc) – Anakhand Jun 29 '20 at 14:30
  • Does this answer your question? [Is a subclass Liskov Substitutable if it disallows the same invocation of the constructor in the child as in the parent?](https://softwareengineering.stackexchange.com/questions/411048/is-a-subclass-liskov-substitutable-if-it-disallows-the-same-invocation-of-the-co) – Bart van Ingen Schenau Jul 02 '20 at 14:30

2 Answers2

11

As you may have already guessed, the constructor of your implementing class does not participate in the API of the interface. In fact, you wouldn't want the constructor to be part of the interface. Doing so would mean that your interface would have knowledge about how the class is instantiated, which would almost certainly foil design patterns such as Abstract Factory, Service Locator and Dependency Injection.

No, you want your interface to be constructor-agnostic, so that you can instantiate the implementing class in any way you see fit, whether that's through a Constructor, using Reflection, or by making use of an IoC container.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
1

The Liskov substitution principle is really referring to behavior more than anything else. Subtypes of a class should extend functionality but only in ways that don't disrupt the current functionality in the context of your program.

In this regard, methods and constructors can take on additional parameters. The trick is that you could use RepositoryUser and BillingRepository as IRepository instances interchangeabily throughout your program and they should both be used in the same way. The difference, where it counts, should be in the implementation details and nowhere else.

The construction of an instance should also follow Liskov principle, but only in the case in which the constructor is performing logic of its own (calling methods and the like). However it is usually best practice to avoid doing so in the constructor, and if that is your case, you need not worry about how the object is instantiated for what concerns Liskov principle.

Neil
  • 22,670
  • 45
  • 76