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 ?
-
1Does this answer your question? Where does the Liskov Substitution Principle generally lie in different constructor parameter lists?Anakhand– Anakhand06/29/2020 14:30:16Commented Jun 29, 2020 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?Bart van Ingen Schenau– Bart van Ingen Schenau07/02/2020 14:30:07Commented Jul 2, 2020 at 14:30
2 Answers 2
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.
-
Thank you for your reply it's a bit clear. And I think in this case, I m respecting Liskov Principle.Thomas thomas– Thomas thomas11/13/2015 07:37:06Commented Nov 13, 2015 at 7:37
-
2LSP isn't even a factor here.Robert Harvey– Robert Harvey11/13/2015 07:38:12Commented Nov 13, 2015 at 7:38
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.
Explore related questions
See similar questions with these tags.