Okay, so it's time to solve this particular problem which we got, which we discussed in our previous video. before I proceed to that, I hope you guys remember the statement of the liskov substitution principle, which is trying to tell us that a parent class cannot replace the child class seamlessly. And we understood one thing that we have a parent class, which is invoice and our child class, which is complex invoice. And somewhere if my child class is just going to have some new methods, and it's not going to overwrite the logic of my parent class, then there will be no problem. But in our case, we need a new kind of calculated tax, which is based on the second tax rate. And that's why we have to redefine the logic of calculated tax.
And that's why we have created this new keyword and we have done all this logical thing. But this is where liskov substitution principle is not satisfying is failing. And that's why when To find out a solution of this. Now in this video, I'm going to give you that solution. But before I give you that thing, let me tell you one thing. There are two different ways to satisfy this core solution principle.
One is with interface, and another one is without interface. What I'm going to show you right now is without interface, the reason behind that is most of the time when people use interface to solve this problem. Other people get confused between liskov substitution principle and the principle which is going to come next after this, which is interface segregation principle. That's why to solve the problem of liskov substitution, I'm not going to use interface this time. In my case, I am going to specify that we are going to specify this thing based on the invoice and complex invoice class parent child relationship. So I'm going to remove this inheritance from this and this invoice class is not going to be an any more parent of this complex invoice.
Now when I do this thing, it's showing me that this class is now separate and Independent class, which is going to have a new kind of logic inside that. Now what I'm going to do is from invoice, I'm first copying my two properties which are there. And I'm going to paste of that inside this. So in short, now complex invoice is also going to have three properties like this. And then I'm copying a logic of calculate total inside that, which is going to tell me that we have a logic of calculate tax as well as calculate total. Because this is not again coming from pattern class.
So I'm removing this new keyword from that. And now you can see that complex invoice is an independent individual class, which is not having any connection with invoice. In simple words, to solve the problem of liskov substitution, all I have done is I have removed the relationship between two classes, which is parent and child. And that's why my child class is right now not connected with any parent class. It's actually not a child class anymore is a normal class. And if it is a normal class, it has the individual identity which We can use anywhere without any dependencies.
Obviously, the obvious thing which I need to do next is like the invoice modifier which is helping me to modify the invoices. I need another class which is going to be a new class with the name, complex invoice modifiers and this complex invoice modifier is going to help me to modify my complex invoices, and this complex invoice modifier is going to help me to modify the invoices which are using that complex invoice class. The logic of this complex invoice modifier is going to be very much similar to invoice modifier. That's why I'm going to do copy and paste but the only thing is it's not going to have a connection with invoice class is going to have a connection with complex invoice class and that's why my private variable and my parameter of my constructor both are going to have a connection with the complex In what's the moment we do this thing, it's something like this that we have created a duplicate core kind of thing.
Like if you check everywhere where we are doing all this thing, we are actually associating the similar kind of logic again again again. So whatever we have done for the invoice we have done similar kind of thing for complex invoice and complex invoice modifier. Now, I know if people are going to blame me for this that this is a duplicated code. I agree that this is something which is not a good practice to do in projects. But this is what a Lesko substitution principle is trying to tell you. And this is what you have to do only when you have a child class, which is having a new kind of implementation based on the parent.
If you have a parent and child who are not using any new implementation inside the child, then again you're using a 10th and you deal with that. The another way to solve the risk of separation of principle is in spite of creating a duplication kind of class like this. You can To an interface which is going to have abstraction. And that interface, you have to implement an invoice modifier, as well as complex invoice modifier. And that will also follow the same purpose. But in my video, I'm not doing that thing because in my next video, I'm going to show you Principle number four, which is interface segregation principle.
And in that only I want to use interfaces so that my audience should not get confused between interface usage inside these two principles. So guys, this was Principle number three, this co substitution principle, which is focusing on the inheritance of parent child classes. And it's saying that parent class cannot replace the child class seamlessly. I hope you understood this. Thank you.