In that last video, I mentioned the basics of this 'Has-a' containment structure, where one class has within it an instance of another class, such as our Wizard class having a field of type Weapon. There is another way to incorporate code from another class, an outside class, and that is with inheritance, but it does so in a very different way than we have seen so far. We've shied away from talking about inheritance, I think we're ready to talk about it now. Inheritance is very simple at the heart of it, and is a way of associating classes in much the same way we think of class hierarchies in the real world. Remember we were originally talking about a class for human, a human class or a person class. What broader class can you think of that humans, as a class, inherit characteristics from? That you can say they inherit characteristics from. That is to say all humans are also a subclass of this other class. How about mammals? All humans are mammals, which is a broader class that can apply to humans as well as other animal classes.
Let's write out how this would look like in code, when inheriting having a Human class inheriting from a broader Mammal class. The first thing we're going to want to do is, as usual, create a new script for this. Let's create our Pure C# classes first. Let's call this AnimalClasses. As before, we don't need to inherit, nor do we want to inherit, from MonoBehaviour. The first thing we'll do is we'll create our Human class, as we did before, at least very similar. Let's just rename that to Human. For the Human class, let's just give it a somewhat unique feel that would be unique to the Human class. Let's say "public bool Bipedal." Walks on two legs. We'll set that to true. Not that we have to, but just to illustrate our point. In an entirely different class, which we can write anywhere but we'll write it above our Human class, let's make our Mammal class, and within it, give it some field that is essential to that particular class, some essential field that belongs to all Mammals. How about let's say this. public bool LaysEggs We'll set it to false, again, just for illustrative purposes. Now, let's do this. Let's simply inherit from that Mammal class, so Humans inherit the characteristics, the fields and such from the Mammal class, simply by referencing the Mammal class with the colon here. When that comes after the class name, this means "inherits from," that's how you can read it, and then you simply reference the outside class, in this case the Mammal class.
Then to see the result of this, as usual, we'll make a separate class so we can create our instance and so forth. We'll call this script, AnimalFactory. It derives from MonoBehavioru, as usual, and we'll preserve the Start() method as usual as well, so we can use it to output to Unity. In the Start() method, write this. We'll create first our instance of a Human, call it person = new Human() We've got our instance now. Now to our Debug.Log(), watch this. Let's output the fields available to us in the person variable object instance. person, and with IntelliSense, after hitting the dot accessor, I get not only Bipedal, which is directly a field that is made available within our Human class, but we also get the LaysEggs field. Now let's go to Unity. Attach that factory script to our test game object, as usual, and we'll output it, just so you can see. False. In case it isn't obvious, that's the value that we set for lays eggs, going back to our animal classes. That's why that's outputting. As you see here, by inheriting from the class "Mammal," we're quietly importing all of the fields and methods defined in the Mammal class into the Human class. You can see just with IntelliSense alone how that's the case. I just showed you that when we were referencing the LaysEggs field.
Now, this containment structure has its own uses. As you recall, our game scripts that we've been writing so far have all been inheriting from MonoBehaviour, and that's why I'm mainly showing you inheritance right now. In contrast to the Has-a containment structure that we saw in the previous video, this inheritance structure would be called an "Is-a" structure. In other words, a Human is a Mammal, where as before we had a Wizard has a Weapon, with that containment structure. Just like the code reuse benefit we got from the Has-a containment structure, we were able to reuse that object from the Weapon class blueprint in both the Wizard and Knight class. We just reuse that code there. We're able to reuse it in those different classes. Just like that reuse benefit with that Has-a containment structure, where multiple classes can incorporate other classes' code by having it as a field, for example, you can get code reuse with inheritance by having other classes inherit from it as well. Let's illustrate that with this example. Let's make another class that can inherit from the Mammal class. How about class Dog, inherits from Mammal. It can have its own fields along with now inheriting the LaysEggs field, just like the Human class had its own class for Bipedal. It's actually important to realize right now that when you see this, it's not an empty class. It would be an empty class if we didn't inherit from Mammal, but make no mistake, there's this code that is being inherited, and you'll see this often in Unity where classes might look relatively small, but they're actually much larger simply by virtue of them inheriting or from being a sub-class of outside classes. We'll just give the Dog class its own Bipedal value, which we know is false. Four-legged, right?
In the end, the way we gain access to that code from the outside class, from inheritance is a bit different than if we did it through containment. As with inheritance, we're directly importing the inherited code. In an Is-a inheritance relationship between classes, it'll make most sense to use that when several classes have the same basic code definition with maybe minor differences, because inheritance actually allows us to be more flexible with those differences than with simple Has-a containment would allow. It lets us override inherited properties or fields and methods, for example, but I don't really want to get into that just yet. Just do know that and keep that in mind, that that's where it's useful. It's up to you ultimately in the end, as the programmer with all these tools being given to you, to choose an inheritance versus containment structure where and when you see fit. There isn't really anything written in stone. The Is-a and Has-a idea that I've been presenting to you is just a guideline. In some cases, it may make more sense to inherit code from another class than have an instance field of that outside class, or vice versa.
We won't really go too deep into showing you this where and when you make this choice. A lot of it becomes intuitive or becomes a matter of choice. Different programmers will have very different ways of representing or solving problems in code. I just wanted to show you the basic principles of inheritance right now and contrast it with this Has-a containment structure, for the purposes of understanding Unity's code base in general, which itself makes extensive use of both inheritance and object containment. That's why we're looking at it right now.
Lesson 22 - "Is-A" Inheritance Containment