Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
So the next point I want to dig into is point nine, thou shalt use composition over inheritance.
What does composition and inheritance mean?
Why should we prefer one over the other composition over inheritance?
So a classic example of where inheritance can go wrong is the following.
Imagine we start off with an animal class and that's going to be our super class is going to be what
we inherit from.
If you are not too familiar with inheritance, this is where we take all of the functionality of this
class.
Essentially, we say anything that I inherit from it is one of these.
It has all of that and more.
So a mammal, for example, might be a type of animal.
Not all animals are mammals, but all mammals are animals.
And so a mammal will have all of the functionality of the animal.
It will be an animal.
So if an animal has a live method implemented here, then an animal also has that live method.
It automatically inherits that from the animal class.
The mammal, however, can add its own functionality as well.
As you can see here, the mammal adds on the functionality of being able to make milk, and anything
that inherits from the mammal will be able to make milk.
We might have another subclass of animal, which further specializes in or specialize it differently
to the mammals such as reptile, which allows it to lay eggs that gives it that functionality there.
And then we can actually inherit some actual instances or some actual classes from this that we might
instantiate, such as the cow or a snake from reptile.
And you can see how they're going to get all of the appropriate functionality here.
Cow gets to make milk and live, the snake gets to lay eggs and live, and they share the common functionality
of living, but they get to differentiate functionality as well.
This all seems fine and glorious and really easy up until the point where you find something that doesn't
match your inheritance taxonomy.
So you might find something like a platypus, which suddenly doesn't inherit from mammal very easily
because it wants to be able to lay eggs.
But it doesn't inherit from reptiles because it's warm blooded and it needs to make milk.
So why do we inherit from?
And this is a very common issue with inheritance.
You will find that stuff kind of starts to happen.
You'll find things that you want to inherit from multiple places and languages like C Sharp will not
let you inherit from multiple places because then you wouldn't know.
For example, if I were to call the live method on platypus, do I call it via the mammal side or the
reptile side?
What if the reptile had overridden it?
And so it gets very confusing.
And obviously a platypus isn't really a reptile, but it does have the ability to lay eggs.
This gets very confusing composition.
On the other hand, it can be a lot more powerful.
It can be a lot more verbose as well.
It can mean that we have to write methods that expose the functionality of these components.
It can be a little bit more complicated than inheritance, but it can save us a lot of that kind of
hassle.
So you may be familiar with composition in the sense of unity components.
We can take a GameObject and add all sorts of different components to it to make it behave how we want
it to.
So instead of having a player class, we'd have a player game object and we would give it a movement
component.
We would give it some particle effect components, we'd give it some animate components and that the
combination of those components, the composition of those components gives it its actual functionality
and those components have to coordinate between themselves.
So we could do the same thing with a cow.
And in this case, you could still have a coordinating class.
You could still have a cow class that coordinates and composes a bunch of functionality driven components.
So, for example, we might have a milk making component.
The cow will have a say.
You notice the change in language here.
Inheritance we talk about is a would say the cow is a mammal.
Here, we're saying that the cow has a milk making component and it would need to write some wrapper
functionality to make sure it is calling to that make milk function in the right places and so on and
so forth, but is able to reuse that functionality at will.
And the snake could have an egg laying components and similarly could cool to that functionality.
And now the platypus has got a very easy choice of simply including both being able to have a milk making
component and have an egg laying component.
And composition and inheritance isn't an either or situation.
You could easily have both of these.
You could have that the mammal has a milk making component that you have.
The reptile has an egg laying component, and the platypus is a mammal that also has an egg laying component
so you can start to mix and match these things as well.
But what we're saying here is that try and put more of your heavy functionality into components.
They are far more reusable.
They are far more flexible than trying to stuff all of that functionality into parent classes and an
inheritance.
Try and use the inheritance as little as possible, try and use components as much as possible.
And that's what composition over inheritance means.
It is not a hard and fast rule saying that you must use competition all the time and never use inheritance.
It's saying try to use one more than the other.
So let's have a little challenge to see if you can figure out where this picture goes wrong.
This is an inheritance hierarchy, and what I've listed out is some of the functionality that you might
expect to see in these classes.
So at the top level, we've got a character that has a shared functionality between a player and an
enemy.
It is able to do locomotion, so moving around the world, it's able to attack it.
It has health, these kinds of things.
We want both a player and enemy to have great.
So we inherit in player and enemy from the correct class.
The player adds a layer of player control logic.
It also adds some upgrade ability, such as maybe in an RPG, you are able to level up your character.
The enemy, on the other hand, does not have the upgradability.
Enemies are kind of more fixed and programmed into the level.
However, they do have air control and they are programmed to be hostile to the player when you approach
them.
This seems fine and great, but can you imagine what you might add to this game that would break or
encourage you to have bad inheritance here or mean duplicated code?
Have a pause?
Have a think.
See if you can think of anything, any type of class here that we'd add and wouldn't match in here.
OK, so what I'm thinking is we could be adding in an NPC, for example, an NPC would need some shared
functionality from the character.
It would need the locomotion, it would need to be able to probably wouldn't need to be able to attack.
So it's going to inherit functionality it doesn't need.
So that's something that's not great already.
It's going to inherit a health.
Maybe you don't want to be able to kill the NPCs.
So maybe it shouldn't be inheriting health either.
So you can see how inheritance is already getting as a model without the fact that actually now going
to have some duplicated code because we might want to have air control and share some of that elite
control that the enemies already got, but without the hostility to the player.
So we don't want to inherit NPC from enemy because then it's going to be hostile to the player and somehow
we've got to switch that off, and that's going to be a bit hacky.
It doesn't really make sense that the NPC is an enemy that doesn't make sense from inheritance standpoint.
And one more thing that we can see here is that these classes are violating the principle that a class
should do one thing.
You can see they are managing many different domains.
They're managing locomotion, they're managing combat health.
I control all that sort of thing.
If we split this in two components, it would help on multiple levels.
It would allow us to compose something like an NPC very easily.
We could include locomotion components, but we could exclude health and attacking.
We could include AoE control components but exclude the hostile to the player components, and that
makes a lot more sense.
Now what you can do to get a bit of the best of both worlds and particularly in unity, is to use the
prefab system as a kind of lair of inheritance, which would allow you to say, have a character prefab
and then inherit from that.
And maybe your NPC wouldn't even inherit from character because all you're doing is adding that locomotion
component.
But it allows you to group together some of those common groupings of components and have still a kind
of inheritance structure for when that is useful.
So hopefully you now understand a little bit better why composition is a good idea of why inheritance
sometimes leads us into trouble.
In the next lecture, we're going to be looking in to the rather obscurely named Law of Demand, sir.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.