The Liskov Substitution Principle (LSP) states that an instance of a child class must replace an instance of the parent class without affecting the results that we would get from an instance of the base class itself. This will ensure the class and ultimately the whole application is very robust and easy to maintain and expand, if required¹. In the code you provided, it appears that the `PermanentEmployee`, `TemporaryEmployee`, and `ContractEmployee` classes all inherit from the abstract `Employee` class. The `PermanentEmployee` and `TemporaryEmployee` classes also implement the `IEmployeeBonus` interface. The `ContractEmployee` class implements only the `IEmployee` interface. The Liskov Substitution Principle is not being implemented in this code because the `ContractEmployee` class does not inherit from the abstract `Employee` class like the other two classes do. This means that it cannot be used interchangeably with instances of the other two classes without affecting the results that we would get from an instance of the base class itself¹. I hope this helps! Let me know if you have any other questions. Source: Conversation with Bing, 5/21/2023
This is great video that I thank for. But like other commentators here, I too got confused of some part in the video. First, what happened to CalculateBonus function? Why it is replaced with another function? What if that function is not necessarily required to modify? It might cause to break the application's logic isn't it? I was just thinking that no code changing will be done in that part and make a solution for the given problem.
Great video, thank you! I've learned a lot about the actual reasons behind the SOLID principles. I do have one question: why did you have the Employee abstract class implement the IEmployeeBonus interface? If instead you had the PermanentEmployee and TemporaryEmployee classes do so individually, couldn't you have had ContractorEmployee inherit the Employee class and so employ its constructor and ToString methods?
@@curiossoul In this context, you are right. but to help understand LSP it is required to make different interface so that principle is understood correctly.
Considering the Quote: -- If a program module is using a Base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module -- That is no Exception should be thrown by subclass The Example does not satisfy the Principle, Can you Suggest Another Example ?
I explained this in an interview and interviewer said that I haven't understood the Principle correctly and that I need to practically implement and understand. She said if I just go ahead and override getbonus in contract employee and return 0(which is perfectly valid scenario) then why do I need to segregate Employee class functionality into different interface and seperate out IEmployee bonus.
There can be numerous way to do the thing, I don't know what was the interviewer expecations, whether she wanted an example of Liskov principle or just contradict whatever you answered and come up with different stories. I really hate such interviewers who just for belittling ask questions and whether it is even required or used practically most of the time or not.
Wow....Hearty Congratulations Mayank. Very happy for you. Thank you very much for taking time to share the good news. Good luck and all the very best with your new role.
Thank you for watching the video. Really honored with your feedback and Definitely we are planning to come up with a real time project that covers SOLID and DesignPatterns
Hello kudvenkat another solution is derive another abstract class from the abstract class employee for ex bonusEmployee which has the method CalculateBonusSalary() so PermanentEmployee,TemporaryEmployee classes derive from bonusEmployee class and ContractEmployee derive from Employee class.
Your Employee Class don't show your GetMinimumSalary implementation as IEmployee interface required. Also, GetMinimumSalary if that the case, it needs to be virtual so it can be overrode
Hello Avish Was able to understand LSP. However, I do have a question related to one of the guideline that says "Client should not know which subtype they are calling". We have created respective child class instances as needed in the main(). Can this be overcome by something called as Factory method design pattern?. Please correct me if I'm wrong, how can we achieve it. Also, when are you planning to upload the video for "Dependency Inversion Principle"? Thanks,
if we use IEmployee interface for creating Employee object, then we follow LSP but we cannot access bonus methods for permanent employee and temporary employee objects if we use Employee class for creating then ContractEmployee object cannot be created (substituted) so LSP not satisfied so what is the use of LSP if we want bonus method ?
Sir we have defined CalculateBonus in IEmployeeBonus interface and Employee abstract class... Can we segregate this definitions into one? Or if we do then does this satisfy Liskov Substitution principle?
Liskov herself never used the term "Substitute". According to her, it is "behaviour substyping" which states that every subtype should behave the same way it is expected when referencing through parent type as far as methods of parent types are concerned. That means as long as subtypes' implementation of parent type methods are satisfying the characteristics of parent types' methods, it can be called behavioural Subtyping
Also in ContractEmployee Class we need to override ToString method in order to display the employee name correctly, since ContractEmployee Class does not inherit from abstract Employee class...Please correct me if i am wrong :)
You are right. I think pre-written code has ruined this video. Literally, I have watched this number of times to understand. Thank you for your efforts. I hope we do not worry about time while typing the code. Since this basically will help understand more easily.
Amazing explanation sir thank you but I am confused at the end where we missed calling the function CalculateBonus in foreach. What it will do if we call that function?
Thanks alot Avish for videos on SOLID Principles, Can you please let me know how you are able to generate the constructor snippet with parameters? I have tried ctor and tab, tab shortcut, but it generates only empty constructor with no parameters.. thanks in advance.
Thanks for the video, however the contract employee received a bonus of 5000 and the rule was that no bonus was to be awarded. The DRY (Don’t Repeat Yourself) is slightly infringed upon when bonus percentages are the same - but thats a different story. One solution would be to add a simple read-only property in the employee base class named Bonus and returns 0 - then each inherited implementation of Bonus would be calculated inside the getter. (Thats a hardwired approach that matches your example.) I realize that your example is intended to be a simple example to communicate the LSP in C#; however, i believe it’s important to illustrate the S (substitution) helps us and more explanation is required - and you were so close to nailing it! Enjoying your videos!
What if the requirement is to loop through all employess regardless of type (permanent, temp, contract) and display both minimum salary and bonus if there's any? The "LSP implemented" code in this video is not able to display the bonus salary.
Whats the difference in Interface Segregation and Liskov Substitution ??? both have done some duty bothe have separated or divided in multiple interfaces so this Liskov is also looking same as Segregation
we have inherited iemployee in Employee class which has declaration of CalculateSalary() which must be implemented and also have the same method as an abstract method in Employee class. Its so confusing. What my knowledge says is that we have to implement all the elements of interface but we are initializing the employee name and id in employee class instead using the properties from the iEmployee interface.
why would you extend the IEmployee interface in the Employee abstract class and then inherit it in the other 2 classes? Why not directly extend the corresponding interfaces to the classes? Seems bit of an overkill to me
What if the requirement is to loop through all employess regardless of type (permanent, temp, contract) and display both minimum salary and bonus if there's any? The "LSP implemented" code in this video is not able to display the bonus salary. Please answer this question. (Copied from the comment section)
Hi Buddy, Your explanation of the LS Principle, was possibly one of the best that I saw on RUclips thus far. I am subscribing to your channel and have pressed the Bell icon as well. All the very best man! Thanks for your help!
But using IEmployee type list we are not able to access CalculateBonus() method for Permanent and Temporary employee. Then what is the use of creating IEmployee type list? If we need to create 2 type of list Employee Type and IEmployee type every time then i guess its not adhering to LISKOV principle. Please correct me if i am wrong. Also anyone else please give proper solution. Thanks..!!
Please answer the questions in the comment section. It seems incomplete and could land us in embarrassing situations during interviews. Anyways thanks!
You have not used CalculateBonus() method to show bonus, as it will give compile time error because IEmployee interface do not have CalculateBonus() method, which means still child class object is not seamlessly replacing parent class. It seems incomplete.
I have been watching and coding along in VB2017 in order to grasp the details , unfortunately on this video you went bananas and skipped way too much code, if you are presenting code at least try to show ONCE each part of it, without skipping anything so everyone can follow ...
can not understand properly in 1-2 view. Code example better if you can implement live in video rather than copy/pasting or having ready code. The main purpose i could understand. but better if code example you can give at that moment itself like kudu does.
How to call Calculatebonus method by IEmployee object? Calculatebonus method not in use. looks incomplete. Solution : Need to inherit IEmployee in IEmployeeBonus interface. So that we can call both CalculateBonus & GetMinimumSalary methods by using IEmployeeBonus as reference to child class object of PermanentEmployee and TemporaryEmployee.
Why not Employee implements iEmployee , PermanentEmployee & temporaryEmployee inherit from Employee and implement IEmployeeBonus, ContractEmployee inherits from Employee
In a business application validation can be done by a child class but saving can be done by the base. E.g customer can be standard customer, gold customer and platinum customer. Customer earns points after purchases, so Standard customer will become a gold customer and later he will become platinum, more points means you can replace cash with points to pay off whatever the customer bought on credit. In this case, base class Customer which may be an abstract class can handle the save method, as saving the customer information will not change based on the type but validation on the points will change based on the type of the customer. So derived class of Customer class e.g : StandardCustomer, GoldCustomer can override the abstract method validate.
Another good area where bases classes are used in Business Application, Repository Pattern decouples Business Logic from Data Access Layer Technology, here also bases classes and interfaces are heavily used.
With Autofac DI and Automapper, plus repository pattern you can make amazing MVC apps and by using MVVM Prism with WPF u can make enterprise style apps , they all use these base classes and interfaces to achieve it. Rely on Abstraction Not On Concretion is an Object Oriented Principle which will guide you to make decoupled scalable application. This is also achieved by proper use of interfaces and base classes to promote code reuse and decoupling.
This example is very bad, doesn't satisfy the principle the second loop you are not calling Bonus method and that is why is running. I saw a lot of comments saying is clear and good, means that they are not understanding the principle.
in class ContractEmployee.cs // start source code" using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Implemented_LSP_principle.Interface; using Implemented_LSP_principle.Abstract; // Тука ще нарушаваме принципа namespace Implemented_LSP_principle.Implementation { public class ContractEmployee : IEmployee { public int Id { get; set; } public string Name { get; set; } public ContractEmployee() { } public ContractEmployee(int id, string name) { this.Id = id; this.Name = name; }
public decimal GetMinimumSalary() { return 50; } public override string ToString() // you don't putt this in .... why ? // { return string.Format($"ID : {this.Id} Name : {this.Name}"); } } } "end source code
Employee ID : 1 Name : John Bonus: 10000.0 Minimum Salary: 100 Employee ID : 2 Name : Jason Bonus: 5000.00 Minimum Salary: 40 Employee ID : 1 Name : John Minimum Salary: 100 Employee ID : 2 Name : Jason Minimum Salary: 40 Employee Implemented_LSP_principle.Implementation.ContractEmployee Minimum Salar y: 50
Below is the solution for all of those who are complaining for CalculateBonus is not being implemented at last, and is throwing error. So Please inherit IEmployee form IEmployeeBonus class. internal interface IEmployee : IEmployeeBonus :) Hope it will help someone.
Leave it to an Indian guy to take a complicated subject and make it really easy to understand in under 10 min.
Nice one! Great Explanation!
Perfect playlist. thank you so much for your hardwork and time. Please making contribution to the community. You are making a difference
The Liskov Substitution Principle (LSP) states that an instance of a child class must replace an instance of the parent class without affecting the results that we would get from an instance of the base class itself. This will ensure the class and ultimately the whole application is very robust and easy to maintain and expand, if required¹.
In the code you provided, it appears that the `PermanentEmployee`, `TemporaryEmployee`, and `ContractEmployee` classes all inherit from the abstract `Employee` class. The `PermanentEmployee` and `TemporaryEmployee` classes also implement the `IEmployeeBonus` interface. The `ContractEmployee` class implements only the `IEmployee` interface.
The Liskov Substitution Principle is not being implemented in this code because the `ContractEmployee` class does not inherit from the abstract `Employee` class like the other two classes do. This means that it cannot be used interchangeably with instances of the other two classes without affecting the results that we would get from an instance of the base class itself¹.
I hope this helps! Let me know if you have any other questions.
Source: Conversation with Bing, 5/21/2023
I was wondering how he got the toString implementation in the contract employee class. Did he override it again.
CalculateBonus was not implemented. That's the main thing to see how LSP would work, when one of the subclasses doesn't implement it.
It seems more like interface segregation principle rather than LSP?
No this is LSP, we need to create base class more accurately based on available data and yes it follows ISP as well
So, we are using interface segregation for implementing LISKOV ? please correct me if i'm wrong
Same question)) Did you find answer?
@@haykmkrtchyan7093 yes in code project.
@@maheshreddy7307 so is it also an interface segregation?
This is great video that I thank for. But like other commentators here, I too got confused of some part in the video. First, what happened to CalculateBonus function? Why it is replaced with another function? What if that function is not necessarily required to modify? It might cause to break the application's logic isn't it? I was just thinking that no code changing will be done in that part and make a solution for the given problem.
Great video, thank you! I've learned a lot about the actual reasons behind the SOLID principles.
I do have one question: why did you have the Employee abstract class implement the IEmployeeBonus interface? If instead you had the PermanentEmployee and TemporaryEmployee classes do so individually, couldn't you have had ContractorEmployee inherit the Employee class and so employ its constructor and ToString methods?
I was about to ask this. Another reason is the naming convention. A contractor is also an employee so must be named correctly.
@@curiossoul In this context, you are right. but to help understand LSP it is required to make different interface so that principle is understood correctly.
Considering the Quote:
-- If a program module is using a Base class,
then the reference to the Base class can be replaced with a Derived class
without affecting the functionality of the program module
-- That is no Exception should be thrown by
subclass
The Example does not satisfy the Principle, Can you Suggest Another Example ?
What about CalculateBonus?... at the end
I explained this in an interview and interviewer said that I haven't understood the Principle correctly and that I need to practically implement and understand.
She said if I just go ahead and override getbonus in contract employee and return 0(which is perfectly valid scenario) then why do I need to segregate Employee class functionality into different interface and seperate out IEmployee bonus.
There can be numerous way to do the thing, I don't know what was the interviewer expecations, whether she wanted an example of Liskov principle or just contradict whatever you answered and come up with different stories. I really hate such interviewers who just for belittling ask questions and whether it is even required or used practically most of the time or not.
Your example lands me in my new job.. So many thanks :)
Wow....Hearty Congratulations Mayank. Very happy for you. Thank you very much for taking time to share the good news.
Good luck and all the very best with your new role.
Thanks a lot Avish.
It will be great if you show us a real time project using all the design patterns and SOLID principles in future.
Thank you
Thank you for watching the video. Really honored with your feedback and Definitely we are planning to come up with a real time project that covers SOLID and DesignPatterns
@@avishmsd1651 Is it the real time project out now?
Hello kudvenkat another solution is derive another abstract class from the abstract class employee for ex bonusEmployee which has the method CalculateBonusSalary() so PermanentEmployee,TemporaryEmployee classes derive from bonusEmployee class and ContractEmployee derive from Employee class.
Your Employee Class don't show your GetMinimumSalary implementation as IEmployee interface required. Also, GetMinimumSalary if that the case, it needs to be virtual so it can be overrode
Appreciate your efforts to help others. try to type code in video as it help for starters otherwise its all good
Hello Avish
Was able to understand LSP. However, I do have a question related to one of the guideline that says "Client should not know which subtype they are calling". We have created respective child class instances as needed in the main(). Can this be overcome by something called as Factory method design pattern?. Please correct me if I'm wrong, how can we achieve it.
Also, when are you planning to upload the video for "Dependency Inversion Principle"?
Thanks,
if we use IEmployee interface for creating Employee object, then we follow LSP but we cannot access bonus methods for permanent employee and temporary employee objects
if we use Employee class for creating then ContractEmployee object cannot be created (substituted) so LSP not satisfied
so what is the use of LSP if we want bonus method ?
Super explanation!!
Thank you so much for your explanations! It's very clear!
Sir we have defined CalculateBonus in IEmployeeBonus interface and Employee abstract class... Can we segregate this definitions into one? Or if we do then does this satisfy Liskov Substitution principle?
Liskov herself never used the term "Substitute". According to her, it is "behaviour substyping" which states that every subtype should behave the same way it is expected when referencing through parent type as far as methods of parent types are concerned. That means as long as subtypes' implementation of parent type methods are satisfying the characteristics of parent types' methods, it can be called behavioural Subtyping
Excellent tutorial. Thanks a lot.
Also in ContractEmployee Class we need to override ToString method in order to display the employee name correctly, since ContractEmployee Class does not inherit from abstract Employee class...Please correct me if i am wrong :)
You are right.
I think pre-written code has ruined this video.
Literally, I have watched this number of times to understand.
Thank you for your efforts. I hope we do not worry about time while typing the code. Since this basically will help understand more easily.
You are Great!
Amazing explanation sir thank you but I am confused at the end where we missed calling the function CalculateBonus in foreach. What it will do if we call that function?
It will give you compliation error because calculate bonus is not part of IEmployee.
Thanks alot Avish for videos on SOLID Principles,
Can you please let me know how you are able to generate the constructor snippet with parameters?
I have tried ctor and tab, tab shortcut, but it generates only empty constructor with no parameters..
thanks in advance.
In Visual Studio Pro 2017, move cursor to code line of class, then Alt+Enter. You will be presented with Generate Constructor options.
Thanks for the video, however the contract employee received a bonus of 5000 and the rule was that no bonus was to be awarded.
The DRY (Don’t Repeat Yourself) is slightly infringed upon when bonus percentages are the same - but thats a different story. One solution would be to add a simple read-only property in the employee base class named Bonus and returns 0 - then each inherited implementation of Bonus would be calculated inside the getter. (Thats a hardwired approach that matches your example.)
I realize that your example is intended to be a simple example to communicate the LSP in C#; however, i believe it’s important to illustrate the S (substitution) helps us and more explanation is required - and you were so close to nailing it!
Enjoying your videos!
What if the requirement is to loop through all employess regardless of type (permanent, temp, contract) and display both minimum salary and bonus if there's any? The "LSP implemented" code in this video is not able to display the bonus salary.
We can check it through is keyword.
If(employee is Employee e) e.CalcBounus();
Is it plain and simple co-variance or is there something more to it ??
Whats the difference in Interface Segregation and Liskov Substitution ??? both have done some duty bothe have separated or divided in multiple interfaces so this Liskov is also looking same as Segregation
we have inherited iemployee in Employee class which has declaration of CalculateSalary() which must be implemented and also have the same method as an abstract method in Employee class. Its so confusing. What my knowledge says is that we have to implement all the elements of interface but we are initializing the employee name and id in employee class instead using the properties from the iEmployee interface.
why would you extend the IEmployee interface in the Employee abstract class and then inherit it in the other 2 classes? Why not directly extend the corresponding interfaces to the classes? Seems bit of an overkill to me
For me it was the same interface segregation principle + an abstract class)))
Marvelous
What if the requirement is to loop through all employess regardless of type (permanent, temp, contract) and display both minimum salary and bonus if there's any? The "LSP implemented" code in this video is not able to display the bonus salary. Please answer this question.
(Copied from the comment section)
Amazing!!
Thank you, very well explained
Hi Buddy, Your explanation of the LS Principle, was possibly one of the best that I saw on RUclips thus far. I am subscribing to your channel and have pressed the Bell icon as well. All the very best man! Thanks for your help!
CalculateBonus is not called in the end ?
You said it contract employee is not entitled to a bonus. Why didn’t you have CalculateBonus return 0? Then there is no problem.
But using IEmployee type list we are not able to access CalculateBonus() method for Permanent and Temporary employee. Then what is the use of creating IEmployee type list? If we need to create 2 type of list Employee Type and IEmployee type every time then i guess its not adhering to LISKOV principle. Please correct me if i am wrong. Also anyone else please give proper solution. Thanks..!!
Please answer the questions in the comment section. It seems incomplete and could land us in embarrassing situations during interviews. Anyways thanks!
great videos on SOLID .. waiting for Dependency Inversion explanation
You have not used CalculateBonus() method to show bonus, as it will give compile time error because IEmployee interface do not have CalculateBonus() method, which means still child class object is not seamlessly replacing parent class. It seems incomplete.
This video is blurred. Could replace good video?
please add Azure
Thank you for watching the video. We will try our best to accommodate your suggestion
Sure Sir
You can still throw runtime error with this implementation too
I have been watching and coding along in VB2017 in order to grasp the details , unfortunately on this video you went bananas and skipped way too much code, if you are presenting code at least try to show ONCE each part of it, without skipping anything so everyone can follow ...
can not understand properly in 1-2 view. Code example better if you can implement live in video rather than copy/pasting or having ready code. The main purpose i could understand. but better if code example you can give at that moment itself like kudu does.
Please ask Venkat to make the Videos. You are very poor in explaining things..
anyone in 2024?
How to call Calculatebonus method by IEmployee object? Calculatebonus method not in use. looks incomplete. Solution : Need to inherit IEmployee in IEmployeeBonus interface. So that we can call both CalculateBonus & GetMinimumSalary methods by using IEmployeeBonus as reference to child class object of PermanentEmployee and TemporaryEmployee.
What is the objective of Liskov ? not clear...
I think you'r not kudvenkat
Why not Employee implements iEmployee ,
PermanentEmployee & temporaryEmployee inherit from Employee and implement IEmployeeBonus,
ContractEmployee inherits from Employee
Sir I request to plzz Upload A Demo Project On Asp.Net Mvc ...Some Think Like e -Commerce Website
You should be very careful about creating base classes. If you are developing a business application, base classes are rarely needed.
In a business application validation can be done by a child class but saving can be done by the base. E.g customer can be standard customer, gold customer and platinum customer. Customer earns points after purchases, so Standard customer will become a gold customer and later he will become platinum, more points means you can replace cash with points to pay off whatever the customer bought on credit. In this case, base class Customer which may be an abstract class can handle the save method, as saving the customer information will not change based on the type but validation on the points will change based on the type of the customer. So derived class of Customer class e.g : StandardCustomer, GoldCustomer can override the abstract method validate.
Another good area where bases classes are used in Business Application, Repository Pattern decouples Business Logic from Data Access Layer Technology, here also bases classes and interfaces are heavily used.
With Autofac DI and Automapper, plus repository pattern you can make amazing MVC apps and by using MVVM Prism with WPF u can make enterprise style apps , they all use these base classes and interfaces to achieve it. Rely on Abstraction Not On Concretion is an Object Oriented Principle which will guide you to make decoupled scalable application. This is also achieved by proper use of interfaces and base classes to promote code reuse and decoupling.
Not Satisfied with Explanation ...
At last some real LISkOW Substitution Principle example instead of academic rectangle and square
Unable to understand what he is trying to explain, just reading the sentences than explaining.
The trainer himself is not sure about difference between Interface segregation, Single Responsibility principle and LSP
This example is very bad, doesn't satisfy the principle the second loop you are not calling Bonus method and that is why is running. I saw a lot of comments saying is clear and good, means that they are not understanding the principle.
Still not correct .. I bonus should inherited by permanent employee and temporary employee not employee....
This is a partial example of Liskov Substitution, not completely correct.
Too hurried....
Am I the only one who didn't understand a thing?
in class ContractEmployee.cs
// start source code"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Implemented_LSP_principle.Interface;
using Implemented_LSP_principle.Abstract;
// Тука ще нарушаваме принципа
namespace Implemented_LSP_principle.Implementation
{
public class ContractEmployee : IEmployee
{
public int Id { get; set; }
public string Name { get; set; }
public ContractEmployee()
{
}
public ContractEmployee(int id, string name)
{
this.Id = id;
this.Name = name;
}
public decimal GetMinimumSalary()
{
return 50;
}
public override string ToString()
// you don't putt this in .... why ? //
{
return string.Format($"ID : {this.Id} Name : {this.Name}");
}
}
}
"end source code
Employee ID : 1 Name : John Bonus: 10000.0 Minimum Salary: 100
Employee ID : 2 Name : Jason Bonus: 5000.00 Minimum Salary: 40
Employee ID : 1 Name : John Minimum Salary: 100
Employee ID : 2 Name : Jason Minimum Salary: 40
Employee Implemented_LSP_principle.Implementation.ContractEmployee Minimum Salar
y: 50
Please DO make live content ... or this kind of stuff will be happening ... cheers for video and viewers
Instead of duplicating base class members in ContractEmployee. Virtual method approach would be better. ruclips.net/video/okG3cHgFeak/видео.html
Little bit messed-up content…
Way too complicated explanation
125567890
bal bujaiso miya
"C"?
Grow up.
Below is the solution for all of those who are complaining for CalculateBonus is not being implemented at last, and is throwing error. So Please inherit IEmployee form IEmployeeBonus class.
internal interface IEmployee : IEmployeeBonus
:)
Hope it will help someone.