(light music)
(keys clicking)
In this video, we're gonna start talking about
an object-oriented term called inheritance.
But before I do that,
I want to show you how to the fix the problem
whereby sometimes Android Studio won't compile Kotlin code,
or at least that happened for me,
and I actually found the solution to the problem.
So, just in case you're getting this problem,
this is how to fix it.
Now the problem is, that when I type some code, println,
this is a test, and I've got to run that code,
you can see that println, this is a test,
the code hasn't been executed.
And in fact, what I need to do to get it to work
is make the module,
run it again, and then it'll work.
You can see we're now getting,
this is a test, outputted on the screen.
So the problem's got to do
with the actual build process.
So, you're gonna come up here,
and click on and select,
Edit Configurations.
And the issue is,
that for some reason
this has been set to be just Building.
So we need to actually get it to run the gradle task
to compile the code and then run it.
And that's what's happening
is that's not being executed.
So the fix to this is to select Build,
delete it, then Add.
Your gonna select, Run gradle task.
Then we choose the gradle project,
in this case it'll be the Kotlin Tutorial.
And for tasks, we need to type in
clean build.
(Keyboard clicking)
Click on OK.
So if you already have something that looks very similar
to that you won't need to make this change.
But once we do that,
when we run it
you can see it's now compiling.
And we got the code showing there,
which is fine.
But if I delete this now,
and run this,
we see that the code gets updated automatically
and starts working again.
So it been updated.
So if you did get a problem like that,
that's how to go about fixing it.
Alright, so let's move on.
As I said, in this video
we're going to talk about an object-oriented term
called inheritance
and specifically how that applies to Kotlin programming.
Now, what I'm going to do is start with a definition
and explanation of what it is,
then we'll move into some coding to show you and example
of, with Kotlin, what inheritance is
and also why it's important.
Alright, so let's talk about a
real world example of inheritance.
So, different types of objects in the real world
can have a certain amount in common with each other.
For example, as you can see on this slide,
a Seagull, a Crow and an Eagle,
well they're all birds,
and so are Ostriches and Penguins.
So, in other words they share the, being a bird, traits
so to speak.
They all have a beak and wings,
things they inherit by virtue of them being birds.
Now, another example,
to get away from the natural world,
could be motor vehicles.
A motor car, a lorry and a digger on a building site,
all share common characteristics.
They all have wheels, for one thing,
and are generally powered by and internal combustion engine.
Now, we could say that all these three different vehicles
are descended from a a basic vehicle class.
Now, the basic class probably doesn't have an engine,
it would be an early hand cart, perhaps.
Our three vehicles extend the basic hand cart,
with the addition of an engine.
Now, we're discussing class inheritance,
and inheritance is easier to see in nature,
but I wanted to point out
that the things humans produce also evolve.
They build on earlier versions, adding some features,
and changing the way other features are implemented.
We now have electric cars,
which share a common ancestry with the earlier petrol
and diesel powered versions.
So, I'm gonna stick with birds
because they're easier to understand
than the workings of modern motor vehicles.
Now, our birds share a lot of traits.
They all have feathers, for example,
that's one of the things that makes them birds.
So what we can do ,
is define a base class that objects are based on,
things that are common for classes that use that.
Then we can allow a class
to define the unique characteristics of itself,
just like in the car example.
So, in other words, we have base class,
then something that inherits from that,
to make it something else, to make it unique.
Now, the base class here is bird,
and from that all the birds inherit a beak and wings.
But each type of bird also has things
that make it different from the others.
So, eagles have incredibly good eyesight, for example.
You may be pleased if you spot a Mcdonalds from 400 metres,
but eagles can see a rabbit from two miles away.
So all our birds inherit some basic properties
from their base class,
which is often referred to as the Super Class.
Now, they also inherit methods,
so all birds can walk and eat.
But the individual bird classes also have their own,
unique properties and methods.
Penguins can swim and ostriches can run, for example.
So these individual bird classes
are referred to as Sub Classes.
So crow is a Sub Class of bird,
which makes bird a Super Class of crow.
Now the idea of sub-classing can be taken further,
so we could add subclasses of bird,
such as flying bird and flightless bird.
Now, eagle is a subclass of flying bird
and ostrich is a subclass of flightless bird.
In our example, eagles, crows and gulls
inherit the ability to fly
from the flying bird superclass.
Ostriches and penguins aren't inheriting anything from their
flightless bird superclass in this example,
but they still inherit their beaks and wings
from the bird superclass.
Now ostriches have a run method
and penguins have a swim method,
so a class can introduce other properties and methods,
in addition to the ones it inherits.
Now a class can have more than one superclass
in a hierarchy like in the slide.
Now flying bird is a subclass of a bird,
and eagle is a subclass of flying bird.
So it's also a subclass of bird
because its immediate superclass,
flying bird, is a subclass of bird.
So just to labour the point one more time,
flying bird is a superclass of the three classes
eagle, crow and gull,
and it's also a subclass of bird.
Now at this point, you might be asking,
why bother to go to this level of complexity?
Well firstly, it allows to write code once,
then for it to be used automatically by other classes.
So if we created an eagle object,
it would automatically get beak and wings properties,
together with any other properties and functions
that we'd created in the bird class
without us having to write any code in the eagle class.
So this really leaves you to define
the unique characteristics of a class,
rather than having to reinvent the wheel
each time you create a new class.
Now you can write that common code once,
put that code in the superclass,
and then any class that extends or inherits from,
they're the same thing effectively,
that superclass is going to get the properties and methods
that are defined in that superclass.
Alright, a lot of theory there,
so let's go write a bit of Kotlin code
so this makes more sense.
What we're going to do is,
by starting out is, I'm going to delete the main function,
so that we've just got the definition.
Like you can see on the screen here
that I'm about to do.
Okay, I'm gonna close the run window for now.
We're obviously going to be using this now for our examples.
Now we're going to create a superclass called, Enemy,
which will be the base class for all the things our players
will have to fight in this fictional game.
So we're going to this what we've done before,
right click the Java folder,
click on New, select Kotlin file/class.
Enter, Enemy as the name.
(keyboard clicking)
Press enter there.
Now we're gonna store the hit points,
and also the number of lives,
so we need to create properties for those
in the primary constructor.
And we should also give the enemy a name.
So let's go ahead and do that.
Class.
Enemy.
Parenthesis, val.
Val.
Name.
Colon stream.
And var, hit points.
Colon, int.
Comma, var, lives
(keyboard clicking)
Okay.
So this is a superclass
and any class that extends this enemy class,
or inherits from this class,
because it means the same thing,
should always have name, hit points, and lives properties,
and in a game scenario that's probably quite reasonable
to assume that it's got those properties.
Now by default, Kotlin classes can't be extended,
and if you're use to Java,
its as though we marked the class final.
Now if you're not use to Java,
what that means is that we can't inherit from enemy
unless we mark it as open.
And as we've declared it here,
enemy can't be used as a superclass.
Now the idea is that code would be more robust
if we don't automatically allow classes to be extend.
If you do want to allow it, as we do here,
you have to explicitly tell Kotlin
that the class can be extended.
Now that's easily done.
We just ad the keyword, open to our declaration of enemies.
So we just come back to the start,
and type open.
And now we can use enemy as a base class
for our real enemy types.
If you're not sure why enemy's declared as, val,
but the other two properties are var
then review the earlier videos in this section.
So I'm gonna create a function here,
we're gonna call it, take damage.
We're gonna call this method
if the enemy is taking some damage.
If it's been hit by something.
So we need to deduct the damage from
the number of hit points in that scenario.
So let's go down and write that function.
So it'd be, fun,
take damage,
and in parenthesis, damage,
colon,
int.
And we'll start by typing, val,
remaining hit points,
(keyboard clicking)
is equal to hit points,
take damage.
Then we're gonna do,
if remaining hit points is greater than zero,
I put up a curly block,
then I'm going to do
hit points equals remaining hit points.
Then we'll print a message,
so println, parenthesis, double quotes,
dollar name,
took dollar damage,
points of damage,
and has dollar
hit points left.
Then on the next line,
else,
and I put a curly block,
lives
minus equal one,
and println, dollar name,
lost a life.
So what we're doing here is we're subtracting
the damage from the number of hit points that enemy has
and checking to see if they've still got any left
after that damage is inflicted.
Now if the number remaining is more than zero,
we update the hit points
and print out a message showing how much damage was taken
and also how many hit points are still left.
But if the hit points have dropped to zero below
then we take off a life instead.
Now I don't think we've seen this form of assignment yet,
lives minus equals one, as you can see on line 13.
That's just a shorthand way
of writing,
lives equals lives take one.
So this form's called augmented assignment
and you can use the short hand
with the five arithmetic operators.
Now what I'm going to do is delete that.
What I will do is I'm going to paste in some code here,
comment it out,
and I'm gonna paste this right down at the end of the file.
I'll show you examples of the operators
and the equivalent shorthand version.
Like so.
And you can see the version on the left,
and the short hand version on the right.
So again, that form's called, augmented assignment.
So those examples show you how you can use
augmented assignment operators when you're modifying
the value of something
and assigning the result back to the original variable.
And I've removed that line of code
so make sure if you're typing along you have done that.
That second line allows you to be taking two lives
away from the enemies, which would be cheating a little bit.
Alright so we should probably at this point check
to see if the enemy's got any lives left,
but we demonstrating concepts here,
not creating a full adventure game.
That could be a useful exercise
for you to try out for yourself though,
to make sure that you've understood what we've covered
in this tutorial.
So we basically got a basic class here,
we're storing the name,
hit points, and lives.
So that's the end of the video here.
In the next video, we start out overwriting
the two string function then we'll move on to creating
some other classes.
So I'll see you in the next video.