(playful ambient music)
Okay, so moving on with the Kotlin tutorial,
I'm gonna go into a bit more detail now
with classes and look at them more in depth.
Now, an important to thing understand,
and it took me a while to get the hang of this
when I first started object-oriented programming,
is that a class is like a cookie cutter, or a template,
and from that you can create an unlimited number
of player objects or player instances.
Now at the end of the last video,
we created four instances from our player class.
So what I'm gonna do is delete the
commented out code firstly, these four printlns,
because we don't need those anymore.
And then just run the programme again
even though it's still showing on the screen,
just to remind ourselves what it was doing.
And you can see it's outputting the four
four player instances there and their values.
So we're getting four totally separate objects displayed,
but they were all created from the same template class,
our player class, in this case.
Now they all have the same properties,
they have a name, and lives, level,
and score properties, but each instance or object
has different values for those properties.
Now they also all have a show method,
or a show function, they mean the same thing.
Kotlin tends to use the term function, by the way,
but the object-oriented term is method.
So you hear me use both words to refer
to a function as part of a class.
Now if you look at the show method, in the player class,
it just prints out the values of the properties
as you can see from lines 7 through 14.
Now each instance of the player class has
different values for the properties,
which is why calling tim.show on line three
of our main method, here,
prints different values to the louise.show on line six.
Okay, so let's extend our player class now
a little bit further.
So we look at our player class again,
so we've got name, lives, level, and score.
And we've used a string and three int types.
But you're not restricted to using
just those types of variables,
we could use an object as a type and a class.
In fact, in Kotlin, string and int are classes,
so we're already using objects.
Now, I'm gonna make more sense if I create an example,
so I'm gonna create this new class called Weapon
to show what I mean there.
So as before, when creating a new class,
you click on, or right click on the Java folder,
or Java directory, New, and select Kotlin File/Class.
And I'll call this one Weapon.
And I'm gonna leave this set to File this time
just to show you what you'd have to do
if you didn't select the class.
And you can see that it's just created a comment,
but it hasn't actually created a class declaration,
so I can actually just type that in manually.
So, class, Weapon...
In this case we're gonna give it some properties
in the primary constructor.
Remember that we define them in parentheses
immediately after the class name,
so we put parentheses there.
So the properties that we want for weapon,
we're gonna start with, val name, colon, String,
comma, then var damageInflicted, colon, Int,
closing parentheses and I'm gonna open the code block,
or create a block of code
using the left and right curly braces.
So a weapon's gonna have a name, like axe or sword,
and we'll store that in the string field,
then we have an int to show how much damage
this particular weapon does.
Now I haven't used any default values there,
so we'll have to specify both values
when we create our weapon objects.
Not that I've made damage inflicted a Var property.
Now it probably wouldn't change
in a normal course of a game like this,
but I want to use it to demonstrate something else soon.
So imagine that there's some magic spell in the game
that can make weapons more deadly or something.
Okay, so moving on, and we've now got
a very simple class that can be used
to represent a weapon in a game.
So let's use this class in our player class,
we'll let the player have weapons.
So we need a property in the player class
to store the weapon in, and it's usual
to declare properties before methods,
so I'm gonna go back to the player class,
we're gonna add this at the start of the class.
So, just below the class definition on line five,
I'm gonna come over here, tab over,
and type var, weapon,
colon, then Weapon, with a capital W,
and I'm gonna press enter.
Now you see that sort of thing done a lot
in Kotlin programming.
The class name normally gives a good indication
of what it represents so Weapon, with a capital W,
tells us that the class represents a weapon.
So that's the type of the property,
and we call it weapon with a lower case w.
Now we could've called it something else,
such as player's weapon or something,
but weapon's a good name for the object.
Because variables in Kotlin are case-sensitive,
Weapon with a capital W
and weapon with a lower case w
are referring to different things.
So here, Weapon, with a capital W,
is the name of the class,
and weapon, with a lower case w,
is an object or instance of that type,
or it will be once we create the weapon.
So you'll see that sort of thing done a lot
when we use Android classes.
And you'll see things like, I'm just gonna type
some code in temporarily, val recyclerViewAdapter,
colon, RecyclerViewAdapter.
That's an example of code
that you'll actually see in Android.
It's very common to use a class name for the variable name,
but with a lower case initial letter.
All right, so I'm gonna delete that line.
Now let's give the player a default weapon,
when the player objects or instances are created.
Now, at the moment we've got an error
in the declaration of our weapon,
and that's because Kotlin wants everything
to be given a value when it's declared.
Now, you'll see ways to avoid doing that,
and of deferring the initial value until later,
but for now we're gonna give everything a value.
So when our players first start playing,
they won't have found any weapons,
so we're just gonna give them a fist to start with.
So we've typed var weapon, colon, Weapon
then we're gonna put after that an assignment,
so, equals, Weapon with a capital W,
parentheses, double quotes, fist,
comma, one, and ending parentheses.
So now, each time we create a new player,
the code will automatically create a new weapon object,
which in this case will be a fist.
Now, they're gonna be finding more
weapons as they play the game,
so that's why I've made weapon a var there.
Now we want to assign different weapons to it ultimately.
Hopefully, you're starting to see when to use val
and when to use var.
Now don't worry if it's still unclear,
just remember you can always change a declaration
if you decide that you should've used var,
for example, instead of val.
So let's actually check if this all works
by printing out the name of Ace's weapon
and the damage it can do in our main function.
So we're gonna come over here to Main,
and we're going to, after this
one2watch.show, we're going to put println,
parentheses, one2watch.weapon.name,
then on the next line, println,
one2watch.weapon.damageInflicted.
First run the programme,
and we can see down at the bottom here,
we've got fist and 1 printed.
So notice how we're still using dot notation
to access the properties of the two classes.
So one2watch.weapon gives us a reference
to Ace's weapon object and we can access
the properties of the weapon by using more dots.
So, .name gives the name of the weapon
and .damageInflicted gives the amount
of damage that weapon does.
Now the name here is a string,
and I mentioned that string is also a class.
So we can expect the string class to
have some functions of it's own,
and it turns out that it does.
So I'm not gonna list them all here,
but a use for one converts the string to uppercase.
So we can come over here to weapon.name,
and at the end of that we can add a .toUppercase.
Select that and press enter.
Now we're using one2watch.weapon to access the weapon,
and using .name to get the weapon's name,
and finally, calling the names toUpperCase function
to convert the name string to capitals.
So you can chain these property
and method accesses as far as you wanna go.
So let's actually just run that to
confirm that it actually works.
Let's see, we've got fist now showing in upper case.
And this chaining is something that you'll
see a lot of in Android programming.
In fact, in Kotlin programming in general, as well.
Many of the built in Java classes have been
designed to be used in this way.
Now, I'm not gonna go into any more
complexity at this stage, but suffice to say,
when we ran the programme as you saw on the screen,
we've got fist now printing out in capitals
So before I finish, we're gonna have a look
at a couple of ways that we can give our players
some more impressive weapons.
Now, the first way is to create a new weapon object,
then assign it to the player's weapon property.
Let's actually have a go at doing that.
So we're gonna come down here.
After the one2watch.weapon.damageInflicted line,
I'm gonna type val, axe
equals, Weapon in capital W, parentheses,
and axe in double quotes, comma, and then 12.
Then we can type gr8.weapon, equals axe,
then we can type println,
gr8.weapon.name,
fix that typo, and on the next line println,
then axe.name.
So we've created a new instance of weapon,
and we assign it to the variable axe.
Then we assign axe to gr8's weapon property.
So gr8 now has an axe as her weapon,
which we can see when we print it out,
so let's just run that to make sure that it works.
And you can see axe is showing there.
Now axe also exists within our main function,
and so we're printing out the value
of the name property from axe on line 18, as well.
So we've got two references to the same object,
one reference is by using the axe variable
and the other's by using the gr8.weapon.
So it's important here to understand that they
both refer to exactly the same object, the axe.
Now, if that seems complicated,
keep in mind that we do the same thing in normal speech.
So someone might refer to my son's wife's father-in-law,
or they may refer to me, Tim Buchalka,
so it's the same person, unless my son has
another wife that we're not aware of.
Now, we can check that they're the same object
by casting that spell I mentioned earlier on the axe.
And we'll increase the damage inflicted by the axe to 24.
So let's actually add the code,
so we'll type axe.damageInflicted, equals 24,
println, axe.damageInflicted.
Let's run that.
So no surprises there, we get 24 printed.
But before I run the programme again
after making this next change,
have a think about what should be printed.
So I'm gonna type in the code first,
so println, gr8.weapon.damageInflicted.
So have a think about what you think
that should print out, the code on line 22.
All right, so let's run that.
And you can see it also shows the value of 24.
So remember that these are two different ways
to refer to the object, the same axe in effect.
So when we change the damage inflicted by axe,
on line 20 to 24, gr8's weapon now does 24 points of damage.
So if you did work out that the programme
should print 24 again, well done.
And if you're not sure why, then it's worth
watching these last couple of videos again.
All right, so I'm gonna finish with the other way
of assigning a weapon to one of the players.
We'll give me a sword.
So we're gonna come down here,
we're gonna type tim.weapon
is equal to Weapon, parentheses,
double quotes, Sword, 10,
and you're gonna println, tim.weapon.name.
So this time we're creating a new weapon,
and assigning it directly to my weapon property.
Now we can see refer to it as tim.weapon,
but we don't have a direct reference to it
in our main function.
So to run the programme,
we can see it correctly prints out sword.
So which way should you use?
Well, the answer is that it depends.
We're gonna be seeing one reason for using
the first method in a later video.
The important thing to consider is
where the weapon, in this case, belongs.
You obviously won't just be dealing
with weapon objects in your code,
but the principle's the same.
In other words, does the axe belong to the player gr8,
or is it part of the game.
Another way to look at that is to ask,
can the axe exist in our programme without the player, gr8?
So I think there's like the names Tim, Louise,
one2watch, and so on, don't have any meaning
without the player that they're attached to.
The axe and the sword, on the other hand,
are part of the overall game.
I could be forced to drop my sword at some some point,
in which case another player might pick it up.
So, if I drop the sword,
let's say I pick up a spear instead.
So, adding that to the code, tim.weapon,
is equal to Weapon, parentheses,
spear, comma 14, and println again, tim.weapon.name.
So if you run this,
so I've now got a spear,
and there's no trace of the sword anywhere.
So the reference to tim.weapon
no longer refers to the sword,
and we can't assign that to another player.
Now, don't worry too much about this.
It's one of the decisions we have to make
when creating our code.
At this stage I just want you to be aware
of the difference and that you can have more
than one reference to the same object.
We'll come back to this in a later video
when we provide a way for our players
to drop things that they've picked up.
So I'm gonna stop the video here,
and in the next one, we're gonna have a challenge
to let you practise some of these techniques.
So see you in the next video.