字幕列表 影片播放 列印英文字幕 Hello, everyone. You've really been loving my solid design principle videos. So here's the 3rd 1 which is going to be covering the list cough principle, which, in my opinion, is one of the most important principles for writing really good object oriented code. So let's get started with that right now. Welcome back to Webb. Have simplified my name's Kyle. And my job is to simplify the web for you so you could start building your dream project sooner. So that sounds interesting. Make sure you subscribe to the channel for more videos just like this one. And now to get started with the list Cough principal, I'm first going to read off the definition, which is that if s is a subtype of tea than objects of type. T may be replaced with objects of type s, and that is a mouthful of jargon that really doesn't make too much sense. But essentially what this is saying this is you have an object, a class. Let's say, for example, you have a class of animal, every single place that you used the animal class. You should be able to replace it with one of its sub classes. So If you have another class called dog, which inherits from animal than every single place that you use animal, you should be able to use dog, and it's going to work just as well as it did before. That is what the list cough principal says, anywhere that you used one type of class. You need to be able to use all of the sub classes of that class, and it should work just fine. So let's jump into an example where we have two different classes. We have a rectangle class, and then we also have the square, which extends rectangle. And that is because we know that every single square is going to be a rectangle because every square is a four sided object and a rectangle is also a four sided object. So we know every square is a rectangle, but not every rectangle is a square. So that's why we have their relation in this direction, where a square extends rectangle and all this is is it takes a constructor, which gives you the width and height. And then there's a function for setting the with studying the height and then getting the area, and then inside of the square. We changed our set with and set height makes You don't even need this area. We changed our set with and set height so that it always gonna set both of the sides. But with and the height toe always be exactly the same. But it's actually a square and not a rectangle. Hence whites in the square class And then we created two rectangles down here. We increase their with and then printed them out. And this increased with function. All it does is it sets the width of the rectangle toe. One more thing what the with currently is. And as you can see, we have two rectangles. This one right here is 10 by 20. This 15 by five. And so when we increase the width from 10 to 11 we get an area of 20 to which we see printed on the right. And here, when we increase the width from 5 to 6, we get an area of 30 which is showing over here. But you may notice that this rectangle right here is actually a square. So we should just change this to be a square change rectangle to to just be square and we can come and replace all of a rectangle two's with square and we should see the exact same thing happen. Everything is gonna be the same over here, right? 22 30 because we're now calling this increased rectangle with with a square, which is a subclass of rectangle. So according to list coughs principle, all of this should work exactly the same as before. But when we run this, you'll notice we get 36. Here is the area of our square and that is because when our square enters this increase with function, it increases the width by one. But that also increases the height by one because our width and height always exactly the same. So now it is a six by six square instead of his six by five rectangle. So this function right here is breaking the lifts cough substitution principle. Essentially, the problem is that our subclass of square is not actually compatible with every function that we're using. A rectangle for our square cannot be substituted in place of a rectangle. So we now are failing that list have substitution principal and this is sometimes a tricky problem to fix. But in this example, one of the easiest ways to fix this would be to change what we're inheriting from. So we want to create another class. This class would be, for example, shape. And this shape class here would actually just have this area function, for example, so we could have an area function and only implemented. And it'll do some kind of code in here to return the area. And then our rectangle is going to extend shape and our square is going to extend shape. So now our rectangle and our square are both extending from shape instead of extending from rectangle. And now our FBI is going to work just fine because when we set the with, for example, and our rectangle, it's going to modify just rectangle stuff. And we would need tohave, for example, increase shape with, but obviously are shaped doesn't really have a with, So this doesn't really work as is, but you get the point that we need to do is we need to create an object that we can actually inherit. The rest of our objects from this example is more so just to show you how the list cough principle works and how code that may look find this rectangle in square code we had before is actually incorrect because it's violating that list cough substitution principle. I have another example that I'm gonna jump to weaken show exactly another way that the Scots substitution principle was violated and how we can actually fix it. So here I have another example of the list cough substitution principal and we have three different classes are first class is our base class, which is a bird, and all of our birds can fly because birds can fly. So we have a five function on our bird. Our next class is a duck class which extends bird because it is a bird and has a quack function because ducks quack. And then lastly, we have a penguin function or a penguin class, which extends bird because a penguin is a bird and penguins can't fly. So we're throwing an air saying, Hey, we can't fi. We can't actually do this, But we also have a swim function because penguins can swim. So it says I can swim and then inside of here we have a make bird fly function which just calls fly on a bird and then we're creating two different birds duck and penguin, and then we're making them fly. And as you can see, the duck prints out. I can fly just fine. But the penguin is throwing an air saying it cannot fly. And this is again another instance of the list cough substitution principle not working because this is a bird function. So it expects a bird class, and we're passing in both of the sub classes a bird, duck and penguin. And according to the principle, every subclass of a class must be able to make this function work properly. And the duck function works fine. So this duck is passing the list cause substitution principle. But the penguin class is not because the Penguin class cannot fly, and thus it works differently than its parents class, which can fly. So we're failing the list. Cost substitution principle and an easy way to fix this is to change it so that we don't just have a bird subclass We have a flying bird some class. So we're gonna say we're gonna have flying birds, and our duck is going to extend from flying bird and then we're also going to create a swimming that bird and then we're going to put our swim method inside of there. So let's just copy that paste that into our swimming bird. And of course, since our penguin can swim, it is going to be a swing bird. We don't need to worry about this five function anymore. Now we can do is we can make a flying bird fly. We can have another function which is going to make a baby swimming, make swimming bird swim and then we're just gonna call swim here. So now we can say make flying very to fly on our duck and we can make a swimming bird swim on our penguin and you can see that works. I can fly and I can swim. And this code right here is passing the list cause substitution principle because every subclass of swimming bird is able to properly call this function and every subclass of flying bird. In our case, duck is able to properly called a make flying bird fly function, and everything is working as if it was the parent class. The code doesn't know that you have a subclass, and because of that, it needs to work as if it was the parent class. But this code has a problem, and this is a problem. I don't really want to get to in too much depth in this video. But it is a major problem with object oriented programming and inheritance in general, and that's that. A duck can also swim so a duck can fly and a duck can swim. But we can't inherit from two different classes you can't inherit from fine bird and from swimming bird you can only inherit from one of them. So what we need to do is maybe create 1/3 class which is flying, swimming bird or something like that, and that really doesn't work very well as you get lots and lots of different permutations of flying, swimming and other types of birds. So what a lot of times you're going to hear about his composition, which is the idea of adding and functionality instead of inheriting functionality. So it add the swimming functionality toward duck and add the flying functionality to our duck without ever extending any based classes. And if composition is something that you want to hear more about. Make sure to let me know it down in the comments below, and I'll make an entire video of composition versus inheritance and why composition is so much better than inheritance. But for the purposes of this video, it's just important to know that as you start following the list cost substitution principle, you may run into issues like this where you have really complex inheritance trees. And if you run into that problem, you need to look at composition as a way to solve that. Because inheritance, when you get into situations like this, convict come incredibly messy and is not the best way to write your code. But for most instances, inheritance is gonna work just fine, and it's not going to be as complex as this. For example, all you need to know, though, for the list cough substitution principle is that if you have a function that accepts a class, every single subclass of that class must also be ableto enter that function and work properly as all there is to the list got substitution principle. So while the definition is really confusing, it's an actually very simple principle to follow and That's all there is to list kind of substitution principle. If you enjoyed this video, make sure to check out my other videos linked over here and subscribe to my channel from more videos just like this one. Thank you very much for watching and have a good day.