In the previous video, we started working with objects and classes.
You got up to speed with that.
It's now time to talk about Inheritance, what that is and
how that applies to objects.
To do that, the best way to get started is to go back and
talk about physical objects again because, the thing is,
different kinds of objects have a certain amount in common with each other.
Using an example of computers, you could say that an iMac computer,
an Android Nexus 9 tablet, and a Dell PC all share the characteristics of
computers, in that they've got RAM, random access memory, ROM, read-only memory, and
they've got a current state as to whether the device is on or off, and so on.
They share common characteristics, but yet each of these devices
add additional features that collectively make them different to each other.
For example, an iMac runs the OSX operating system,
it's got an intel CPU, got a hard drive, USB ports.
An Android Next 9 tablet, for example, runs on the Android operating system, and
it's got a touch screen for input.
A Dell PC runs Windows, it's also got an Intel but maybe an AMD CPU,
it's got a hard drive, a mouse, and so on.
You can see that, while objects can share similar characteristics,
they can also be different as well.
What object oriented program really allows us to do is to create classes
to inherit commonly used standard behavior from other classes.
One of the best ways to actually show inheritance,
rather than giving you a heap of slides discussing it,
is to actually immediately go into some code and actually start working through
some scenarios in showing you what inheritance looks like in Java code.
What I'm going to do is, I'm gonna start with the analogy of an animal.
If you think of any animal,
perhaps certain behaviors that are shared across all types of animals.
For example, animals all eat, they all are able to move in some way,
they've all got a body so that's some of the basic things,
but what about things like, for example, legs?
Well, no, not all animals have legs because snakes and
worms are an example of an animal without legs.
Eyes?
Well, no, not all animals have eyes because there's varieties of spiders, for
example, that have no eyes.
Do they all have a brain?
Well, yes, actually they do, although it does depend on the definition of a brain,
but essentially, yes, they've all got that basic mechanism.
They've also got size, and also they've got a weight as well.
What we could say was,
we could create a very basic class that we could actually apply to each and
every animal out there, and that we know that any animal would have these traits.
We're gonna create a new class now and call it Animal, and we're gonna add some
state and behavior, in other words, field and methods to model that.
Let's do that now, and I've created a new class.
I've created a new project here called Inheritance, so
I'm gonna create a new Java class, and I'm gonna call it Animal.
We talked about those states, so we've got brain, we've got a body, a size,
and a weight, are gonna be our four fields that we're going to apply.
I'm going to create a private field for each of those,
and we're just gonna have an integer, private int brain,
private int body, private int size,
private int weight.
We'll also add another one, and a name because, of course,
every animal has got a name, so we're gonna create a string for that.
We're not gonna be too worried at this stage as to what the contents of these
fields are.
I've designed, as you can see, an integer data type for the brain, body size, and
weight, and likewise a string for the name.
Doesn't really matter too much at the moment as to what type of data we're
going to put in there.
The main thing is what we're trying to do is just come up with characteristics,
state, in this case, of things that all animals have got.
We're also gonna create a constructor so
that we can construct an animal class easily.
I'm going to just use my command to create a constructor, and
I'm going to specify all five as parameters, like so,
and the other thing we'll do is, we'll create a getter for
each of those fields, as well, in case we need to access that later.
That's the basic definition of an animal.
That would be the base class, if you will, that all our other classes that
we're going to create, sort of subtypes of animals, will base themselves off.
Another example of an animal is going to be a dog, so what we're gonna do is create
a class called Dog, but we're gonna inherit from this animal class.
We're gonna go create a new class, call it dog.
In Java terminology, if you want to inherit from another class,
in other words, you wanna be able to access, in some fashion,
the state of behavior that's in that other class, you use the extends keyword.
We type extends, and we type animal.
You can see that IntelliJ has come up and given us choice of animal.
By doing that, we're able to use the state of behavior
that's been defined in the animal class in this new dog class we created.
Now, you notice straight away that I've got an error, so the error that's on
the screen is saying, there's no default constructor available in the animal class.
What that's saying is, look, I'm trying to use the animal class, and to do that,
I need to be able to call the constructor for that class.
That's what we need to do when we're creating a new class that extends
from another one.
We need to be able to call that other constructor class to initialize it, and
if you'll recall, if we go back to the animal class,
we've got a constructor there, so we can initialize those five parameters.
What we really need to do is make sure that we've got a constructor for
the dog class that calls that other class, in other words,
calls the constructor for that other class.
To do that, generate, and just in case you aren't sure how I'm generating that again,
click on Code and Generate.
You can see to the right, in my case, on a Mac, it's Command+N.
You'll go to your operating system, and there'll be a shortcut for your platform,
so choose that to generate a constructor.
You can see that I just literally selected constructor, and
intelliJ actually filled in the rest.
What's happened here is, you can see that automatically, there's those
five parameters that actually are dealing with the animal class, name, brain,
body size, and weight, have been created as parameters to the Dog class,
to the Dog constructor, in other words.
Then this keyword super has come up, so what super means
is to call the constructor that is for the class that we're extending from.
In this case the, superclass.
The super class, or sort of the big class that this class is extending from,
using the extends keyword, or inheriting from, to be more precise.
What this allows us to do is to initialize the Animal class, and if you recall,
the dog is actually part of an animal class, so we've defined an animal class.
We're saying it's based on the animal class, but what we can also do is,
we can add more features to this Dog class.
Things that are unique to a dog and
not just a very generic animal, if that makes sense.
That first line there, what that's done,
it's initialized the base characteristics of an animal, namely the name, the brain,
the body, the size, and the weight, in a constructor.
What we can also do at this point, because we're now working in the Dog class,
is we can assign extra state, extra fields, in other words, and
extra behavior, that is, methods that are unique for
a dog and aren't necessarily applicable for an animal.
For example, we could create some fields, private int eyes
because remembering that not all animals have eyes, but all dogs do have eyes.
Private int legs, not all animals have legs, but dogs do have legs.
All dogs have legs.
Private int tail, all dogs have a tail.
Private int teeth, dogs have teeth.
Maybe another one would be private String coat, would be the type of coat, where
they've got sort of a long silky coat or a short coat and fur, those types of things.
There are unique characteristics relating to a dog that we're adding in addition to
the animals there.
You can see, really, what we're saying is, the dog has got these fields here,
these characteristics, but in addition, they've also got these base
characteristics, but we've defined those in the base animal class because they
aren't specific to a dog, and that's why we're extending from that class.
This is what Java and other object oriented programming languages allow you
to do, is to create a base class that's got the basic information to work on, and
then you can extend from that class, which indeed is very powerful.
Cuz what that also means is not only with the fields, we can also
add specific methods, like, for example, going back to our animal class now,
we could introduce some behaviors, and we could add some methods for those.
For example, all animals have to eat, so we could create a method called eat,
and we won't worry about the functionality for now, but it's there anyway.
Another one might be move.
That's two methods that are unique to all animals.
All animals have some mechanism, some way, to move, and all animals eat in some way,
shape, or form.
By doing that and making it public, if we go back to the Dog class, what that means
straight away is that function, that method, is now available to the Dog class.
The base class we've defined.
We've said, all animals are able to eat
because we specified that method in the Animal class.
This method is inherited from Dog automatically, and
we'll be able to use that, and I'm gonna show how to do that shortly.
Let's look now at this constructor cuz there's two
components that we need to do now if you think about it.
When we're creating a dog, and we're modeling a dog in computer terms,
we've got those parameters that have been defined there, namely the name,
whether it's got a brain, the body, the size, and the weight.
But we also need to initialize those other characteristics as well,
namely the eyes, legs, tail, teeth, and coat.
Really what we'd need to do is,
we would need to initialize that in our constructor, and
not just the fields that we've defined that initialize just the animal class.
Cuz we're now in the Dog class, we're creating a constructor for the dog.
We need to work with these extra parameters.
One of the things we can do is, we can be a little bit smart with our
first definition here with the parameters that need to be passed.
For argument's sake, we're gonna say that all dogs have got brains, so instead of
having to use it as a parameter, I'm gonna remove that parameter there.
I'm just gonna put past the number one,
which really is just our way of saying, all dogs have got a brain.
Likewise, for the body, we're going to do the same thing.
We're not going to put it there as a parameter cuz we're gonna say,
all dogs have got a body.
You can see, we're not done.
I've still initialized the animal class.
It's still got the five parameters it needs, but what we've said is,
we know that all dogs have got a brain and a body, so we're not going to force
the programmer who's creating the Dog class to have to define those.
Well, what we will do is,, we will add these as extra parameters,
so we'll actually add a parameter for the eyes, for
the legs, for the tail, for the teeth, and the coat.
You can see we've used some of those parameters already, and
those parameters that are in the Animal class have been sent on, and
we've executed this constructor, and those fields have been initialized.
What we now need to do is initialize the other ones.
To do that, and you've seen this before,
we'll just do a this.eyes = eyes;,
this.legs = legs;, this.tail = tail;,
this.teeth = teeth;, and this.coat = coat;.
Effectively now we've initialized all of the fields relating to this dog.
Of course, some of those fields were the basic fields that were part of the Animal
class, and the rest were part of the Dog class because they were unique
characteristics related to a dog and not necessarily an animal, which may,
as we've talked about before, may not have some of these features.
Okay, so let's try starting some of this code now,
start using some of this code, creating a new class to see how this works.
What you're going to do first is,
we're going to create an animal, basic animal class.
As you've seen us create new classes before,
we're just going to create that to confirm that it does work.
We'll be creating a new animal class, we've just got the one constructor, and
you can see we need to do a name, so we'll just call it Animal.
Animal.
Then we need a body, so we'll say.
Then we need a brain, so put 1,1,.
We need a size, so we'll just say as the default five and weight five.
You've seen that before.
There's nothing particularly new there, but
that's just the definition for base animal.
It doesn't really make a lot of sense because we want to be specific.
We want to work, in this case, with a dog, so to do that,
to create a Dog class, we're gonna type Dog, dog = new Dog, and
remember the parameters will change, and it'll be here.
So, we might call this dog a Yorkie.
We might say the size is 8, the weight might be 20, 2 eyes,
4 legs, 1 tail, 20 teeth for argument's sake, and
we might say it's a long silky, would be the type of coat.
That's now initializing a dog.
Nothing particularly new there.
You've seen that before, and I'll just fix that typo.
One of the things we can do, this is where inheritance really starts making sense,
is we can start using some of these functions because, remember,
we defined these two public functions, eat and move.
What we could do, we could type dog.,
and notice the eats come up, so we're able to use the method eat, even though if we
look at our Dog class, you can see there's no method definition for eat.
Where's the eat defined?
Well, remember the eat was defined in this class, in the animal class,
so this is one of the features of inheriting from another class.
Because we've defined the method eat as public,
we've said this method is publicly accessible,
the dog class can see that, and it's extending animal.
In other words, it's inheriting from the animal class, and as a result, we're able
to use the eat method, even though it's not actually part of the Dog class.
And just to confirm that, we'll go to the animal class, and
we'll let a System.out.print animal.eat() called,
just so we know that is where it has actually come from and
which part of the code is being executed.
If we run that.
You can see animal.eat() called, so just by that process,
even though we're accessing the Dog class, it knows that the dog is a type of
an animal because we've inherited from the class animal.
As a result of doing that, we're able to access the functionality that's part and
parcel of the animal class, and we are able to use the eat method.
But it does get better than that because what we can also do,
going back to the Dog class, we can override this eat method.
What we can say is, well, like a dog eats in a particular fashion, for example,
the dog chews its food.
All animals don't necessarily chew food, but the dog does chew its food, so
what we might want to do here is, we might want to create a private method
called chew, and this is something unique to a dog.
We'll put something like dog.chew() called,
but then also what we can do is, we can use a generate command again.
I can come over here and I can put in override methods.
Now, what override does, and I'm gonna select that, you can see straight away,
it's given us a list of methods, including the constructor,
that are available in the Animal class.
In other words, it says, okay, I know that you're extending from the Animal class.
These are the methods that can be overridden.
In other words, we can create a version of that same method
that exists in the Animal class, but make it unique for
the Dog class, and that's something that is inherently very powerful.
The other thing I want to point out here is, you notice this java.lang.Object,
I'm going to talk about that in the next video, but what that is,
is that every single class you create, even though it doesn't come up and
show you by the use of the extends keyword, it does actually get extended.
You are extending this object class, which is a special class created by Java, but
more on that in the next video.
For now, let's override the eat method, which is part of the Animal class.
We're gonna create a special method for the dog for eating, so
we're gonna click on that.
Java will come up automatically and give you this @Override symbol, and
that's to remind you that we're overriding a method that is in the superclass.
In this case, it's in the animal class.
Now, both the Dog class has got its own eat method, and
also the Animal class has got its eat method.
What we can then do here is,
we can just put something to indicate that we're calling in here.
We'll put Dog.eat() called, and let's also put chew, and
we'll say the process of a dog eating food is that it's chewing,
so we're gonna call our method that is unique to the dog class, and
then we're gonna use super.eat.
What super means is call the super equivalent of that class, a super., and
the name of the function.
Java will automatically come up here and go, okay, the superclass for
this current class is animal, so it's gonna go back to here and
look at the eat method and call that.
Let's run that and see what happens.
What's happened is the Dog.eat method was called.
If you recall previously, when we called Dog.eat, it went automatically into
the animal method, and it called this method here in the Animal class because,
of course, we did not have an eat method in our Dog class.
Now, we've added an eat method to the dog class.
Dog.eat method has been called first.
We then use chew, which called the private method chew in the Dog class, but
then we use super.eat, which called the animal.eat class.
So, that's using inheritance.
This video is getting quite long.
Let's continue this in the next video.