 Testing, testing, testing. This is a test. One, two, three, test. In our last video, we talked about inheritance. We made a animal and it had mammal that inherited animal. And then we had a feline, k-line, k-line. That's not even a word, k-nine. Hey everybody, it's Brian. This is just a test video. There's a couple bloopers in here, but really I just wanted to see what this looked like once it was actually rendered and done. I've been focusing primarily on Udemy instead of YouTube. I know, shame on me, don't hate me. Unfortunately, if you look at my Udemy stats, that's pretty much all I've done is flutter and dart. So I wanna get back to basics, go back to the core of what Voidrums really was and I'm starting with cute. So I'm making a cute core for beginners, intermediate and advanced, cute widgets, beginners, intermediate and advanced, cute QML, cute embedded, I mean, you name it, I'm doing it, but we've gotta start somewhere. So this is the starting foundation, cute core and this is just a test render. So take one, let's go. Oh, damn, I haven't heard this song in forever. Thumbs up that bad boy. Oh, frick, that coffee is too hot. In this video, we're gonna learn about inheritance. Inheritance is a highly, highly complex topic, but we're gonna make it very simple, very easy to understand. In front of you, we just have a simple program. Here's our main file. There's absolutely nothing going on here. We just have a QDebug and we've got a couple classes. We have an animal, Kline, Phenine, Mammal and there's absolutely nothing. These are just brand new classes that I've made for the sake of time. Now, when we look at these, what we're going to do is we're going to make this animal class and we're gonna have Mammal inherit animal. When we inherit, it's going to inherit all the properties, meaning all the variables, all the functions, all the goodness that goes on in here. And then Kline and Phenine are also going to inherit Mammal. We're gonna see exactly how the inheritance hierarchy tree works. Let's go into animal. First thing you should notice is it is including QObject, meaning yes, you guessed it, this is already inheriting. Animal inherits everything QObject has at the public level. Then we've got our QObject macro letting us know this is truly a QObject. Let's add in QDebug and let's add a few things in here. We're gonna work at the header level just because I don't wanna play around with these files too much. I don't wanna confuse you. We just wanna focus on inheritance. We got a function is alive and we just wanna return true because we really don't wanna work with dead animals. It's just creepy. And we're gonna say void, speak. Let's actually add a QString in here. So right away, you see we've got some functions in here and we could have very easily added these into the implementation files. But like I said, bang, just ignore those for a minute. Let's work at the header level. So animal is already inheriting QObject. Let's go ahead and go to mammal and you'll see it's inheriting QObject as well. Let's go in here and let's say we want animal. So to inherit animal, really all we have to do is replace this QObject. Now, if we try to build this, we're gonna get a build error. Say, ta-da, type QObject is not a direct base of mammal and you'll see it's in our implementation file. So I did lie a little bit. We do have to modify this. This is the constructor and we're not constructing a QObject, we're constructing an animal. But remember, animal is a descendant of QObject. So it has the same constructor. So when we look here, bang. Let's go ahead and grab that. Let's go to mammal. We've got this, it's inheriting that. It's got this, it's inheriting that. Do you understand the distinction here of what's really going on? Let's take a closer look. In the blueprint in the class, we are actually doing the inheritance. In the implementation file, we're doing the constructor here. So let me make sure I'm a QDebug in there, which I do not. Well, that was a fail. And let's actually put this in here. We're just gonna put this in here for demonstrative purposes, but like I said, let's ignore these and focus on what's going on under the hood up here. Now that we're inherited the animal class in mammal, let's go ahead and do that with canine and feline. Let's just grab these. Actually, let's flesh this up real quick while we're here, why not? Because mammals have backbones, we just want to distinguish this. There we go. Now let's go into our feline, bang. And let's make something special just for feline. There we go. Grab this. And we're gonna go into canine and flesh this out really quickly. Never heard a dog bark just once, so we're gonna add a few of these. Bark, bark, bark. There we go. We haven't actually done our inheritance yet, so let's back out and do that. We're gonna go to feline first. Feline's going to inherit mammal, but notice right away, expected class name and Intellisense is not helping us. Remember, C++ is very stupid, so we have to tell it exactly what we want. Let's go ahead and back this out to QObject. Let's change this to mammal. Now, you may be wondering what the heck just happened. Why didn't it understand we wanted mammal? Because animal does not inherit mammal. Mammal inherits animal, so animal has no idea that mammal even exists. Think of the inheritance tree from a top drop, yeah, excuse me, top down. Meaning animal has no idea that mammal exists, but mammal knows everything about animal because mammal's underneath it. Let's jump back to our feline here. And now let's go ahead and inherit the mammal. Grab this, we have to go in here. Let's do the same thing with canine. And let's go ahead and give this a good build just to make sure we didn't miss anything. There we go. We've got a exited normally, so everything works as expected. Let's include our canine and let's include our feline classes. There we go. And let's go ahead and make some instances of these. Now let's call it kitty. Now let's call this the ever descriptive puppy. Okay. So let's go ahead and save this and let's run it and see what happens. Notice how right off the bat, we've got this mammal constructed. What? That's right. We're getting the constructor of the parent class. Let's go ahead and close this and let's add these in here. Let's go back to our main file and run it again. And let's see what's really going on here. You can see we have an animal, mammal, feline, animal, mammal, canine. That gives you our hierarchy tree right here. The first thing that's constructed is animal. Then we're constructing a mammal because remember, mammals inheriting animal. But we're really making a feline, but feline inherits mammal, which inherits animals. So all three of those constructors are fired off because that's what we're doing. Let's go here and let's demonstrate. So kitty can meow, but kitty also has a backbone from our mammal class and do a cute info. You may already have guessed what I'm about to do. Kitty is alive because animals are alive. So this is our hierarchy right here. So this is from the animal class. This is from the mammal class and this is from the feline class. Let's just grab these, throw these right under puppy, magic of copy and paste. Notice how right away there's no meow. We can switch this to bark and you can see our hierarchy tree is much different even though it's the same. So animal, mammal, canine, animal, mammal, feline. Why do we need inheritance? This seems like a lot of work. Well, think of it. You wanna make a car. How many different models makes manufacturers of cars are they, but all cars, well I should say most cars have an engine. They have windows, they have paint, they have tires, they have oil, they have gas, they have all this stuff that makes up the definition of a car. However, let's say a Porsche is much, much different than a taxi cab. There's still cars, but they're different and that's what inheritance really allows you to do. You don't have to reinvent the wheel every single time you do something. Save and run this. You can see what's going on here. We've got our constructors for our hierarchy tree, we're meowing, we have a backbone and we are alive. We're barking, backbone alive. Now, let's talk about another concept really quickly before we close this video out. Let's add a new class here. We call this monster. Help if I can spell monster, right? And we're going to send this from QObject. What we're gonna do in monster is we are going to try to do something called multiple inheritance. I just want to demonstrate something very quickly. If you've been in a C++ class, you have learned about multiple inheritance and it has probably broken your brain. Multiple inheritance is a very, very, very complex topic and it is a royal pain to do correctly. So we're going to inherit from Feline and we're going to inherit from canine. Let's go ahead and go into our monster here. Really don't need to do that, but just want to demonstrate. So we are inheriting feline and canine. So this thing should be able to meow and bark but still have a backbone and be alive according to the rules of C++. Let's even go ahead and include it here and everything seems good so far. And if we say monster, and let's call this monster spaz, spaz.we can bark. Let's look for meow, meow. But what happens if we try to run this thing? You see, we have a problem. Class monster inherits two QObject subclasses, feline and canine, this is not supported. In other words, if you're going to use QObject, you cannot do multiple inheritance. There is a better, more correct way of doing that. It's called implementing an interface which we're going to cover in the next video. But you should be warned before we dive into that video. The specific way of doing it through Qt is you would make one QObject class and then you would add multiple interfaces to it. It's not the same as inheritance though.