We're back with our program that creates Winstons
but I've added a new object type, Hopper,
because Hopper was feeling a little left out.
Now I define Hopper the same way that I define Winston.
Starting off with the constructer function and taking the same properties
and then draw, and talk, and then I also added another method called Horray
because Hoppers really like to celebrate and Winstons don't really at all.
Now at the bottom of the function, I've created two new Hopper objects:
Little Hopper and Big Hopper
and drawn them and called talk on one and Horray on the other.
So that's pretty neat
Now, if we look at this code up here, you might notice something interesting.
The code for hopper is very similar to the code for winston.
Particularly look at this constructor. I don't know if you remember but that is
exactly the same code as our Winston constructor function.
And then this talk function, is also exactly the same code
as our Winston talk function, and they also both have draw functions.
So there's a lot of things in common about these two object types
and that makes sense because Hopper and Winston
they're two very similar object types in our world.
If you think about the real world, outside the computer,
most object types shares similarities with other object types.
Like in the animal kingdom. All animals are similar in some ways.
And then we have different types of animals, like humans.
Humans share those similarities but also have their own unique similarities.
So we could say that animal is an object type
that human object types inherit functionality from.
We don't completely start from scratch.
We add on top of the functionality that we get from being an animal.
Like all animals make noises, but humans also make language.
So this concept of object inheritance is really useful in programming too.
And we can create a chain of object inheritance in our Javascript.
So to do this when you think about what's shared about our object types.
And come up with a name for that
'cause we're going to create a new object type that represents
the base object. So let's call them creatures.
They're both creatures.
So we say var creature equals...
And now we need our constructer function So let's go and just steal Hopper's
since that's the same thing that Winston has. Alright.
And then... let's see. Now we want to... What do we want to do next?
Maybe we want to add the "talk" function on it.
Talk function, we could just steal Hoppper's.
But of course we need to have it on the creature's prototype instead.
Okay, cool. So now we have this creature object type.
But we need to actually tell Hopper
that Hopper should actually base it's functionality off of creature.
So we can do that by writing this line here.
We'll say "Hopper.prototype equals object.create, creature.prototype"
So what this line does, tells Javascript to base Hopper's prototype,
so to base all of Hopper's functionality, off of the creature prototype.
That means that every time it looks for a function on a Hopper,
it'll look at Hopper's prototype first, but then if it doesn't find that
it'll actually look and see if it was on the creature prototype.
And this is what we call the prototype chain.
Now, once we've done this we should actually be able to
delete the talk function on Hopper because it already exists on creature.
Which is up the prototype chain, so let's try it. Ready? ♪Dun dun dun♪
It worked! And it works because it finds it on creature prototype instead.
So let's try deleting it on Winston too.
Okay. It didn't work it says "object has no method 'talk'".
And why is that? Well we have our Winston constructer
and draw and we took away the talk.
Well, you notice we forgot to actually tell Winson's prototype
to be based off the creature prototype.
So we need that very important line. Winston.prototype=object.create
(Creature.prototype)
Ta Da! And notice something important.
I have this line after the constructor function
but before I add anything else to the Winston prototype.
So that's usually what you want to do. You want to tell it
just as your starting off immediately:
what your initial prototype will be based on.
But then we keep adding more stuff to it's prototype.
Because there could be some things
that are unique to Winstons or unique to Hoppers
that aren't on creatures.
And that's totally cool that you can define those.
Alright. Now, if we look at this we still have some repeated code.
The constructor code.
Right? We have this all three times.
So could we just delete it? Let's try it.
Okay. Hmm... Doesn't seem like that worked
'Cause our Hopper shows up in the upper left corner.
It kind of forgot everything about itself.
And this is because Javascript does not assume you want
the same constructor even if you want to base the prototype off of it.
It lets you define your own constructor for these objects.
But it also does give you an easy way to call a constructor from a sub-object
The way we can do this is, we will write
creature.call(this,nickname,age,x,y)
Now what this does--notice it worked. yay. And what it did actually
it's calling the creature function, --the construction function.
It's calling that function but it's passing and saying,
okay you should call this constructor function as if
it was being called from this Hopper object
and as if it's being called with these arguments.
These are arguments that the Hopper got called with.
And that will end up just executing this code as if it was right here.
And that's exactly what we want. And it worked.
And we can go ahead and
copy this line into the Winston constructor too.
And it works. Yay!
Alright. So check this out. We've encapsulated all our shared
properties and functionalities about objects in this single base
object type: creature
And we've made two object types that extend from that base object.
They inherit some functionality but they add their own too.
And the cool thing about this
is that we can change the shared functionality in a single place.
Like if we wanted to change age again. We could say "+ yrs old".
Cool, now everybody has "yrs old" at the end of it.
Or we could change the "talk" functions and be like "suppp?!". Woo!
And now both Winstons and Hoppers are saying "sup".
So now that you've seen how to
create object types and inherit from object types,
you can start thinking about how this might be useful
in your drawings and animations and simulations and games.
For example, maybe you have a game and you have many types of characters in it
All of them can run but only some of them can jump.
That's a perfect place for some object types and some inheritance.
But I bet you can think of tons of more ways as well.