Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's learn about constructors to require information at object creation time.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
Okay, so we have a problem.
0:00
Every Pez dispenser we create
is currently hard coded to Yoda.
0:03
Now, hard coded meaning it's
permanently set to a value.
0:07
So that's not really what we want, right?
0:10
We want to allow that character
to be configurable, but
0:12
really only at creation time.
0:16
We'd like to allow consumers of our code
to create whatever character type of
0:18
Pez dispenser they want when
they create a new one, but
0:22
we don't want it to change
after it's created.
0:26
The common solution to this problem is to
create what is known as a constructor.
0:29
A constructor is a method that will
run when you instantiate the class.
0:33
Again instantiation happens when you
create the new instance of the class
0:38
using the new keyword.
0:42
A constructor is a great place to stick
required information about the initial set
0:44
up of the object.
0:48
Let's go create a constructor for our Pez
dispenser class that allows a consumer to
0:50
specify the character name upon
creation of a new Pez dispenser object.
0:54
>> Okay, so like I said, constructors
look and behave a whole lot like methods.
1:00
They have an access modifier, so
we'll set that to public, say public.
1:05
And what identifies them as a constructor
as opposed to a method is that there is
1:11
no return type, but then it's
followed by the name of the class.
1:15
So we're gonna, the name of the class as
PezDispenser, so PezDispenser, right.
1:18
The name of the class is PezDispenser,
1:22
and the name of our constructor
is PezDispenser there, so.
1:25
And then we'll add parentheses
to make sure that this callable,
1:28
just like we do for methods, right.
1:32
Remember we made the parentheses here so
it looks like a method.
1:33
And now we need to define our parameters
like we did with string contains.
1:36
Now these describe to our caller
what is expected to be passed in.
1:39
So we want the creator of our
object to specify the name.
1:43
So let's add that as a parameter.
1:47
So we're gonna say, String name.
1:49
So that should be a nice
clear understandable name.
1:52
And then we're gonna close that off and
we're gonna open up our curly brace to
1:54
start a new scope, and
I'm gonna immediately close it.
1:58
And inside of here we want
to set the private field
2:01
character name to what was passed in,
right.
2:05
So we're gonna say, CharacterName = Name.
2:09
The constructor just like the method has
access to these private member fields.
2:14
Since we've now required the name to be
set from the caller of the class, let's go
2:19
ahead and remove this Yoda instantiation
here, and we'll just close that.
2:24
So now the variable has been declared but
not initialized.
2:28
All right, so I'm going to save this.
2:31
And if I flip back to example.Java we
can see that the code will not compile.
2:34
So it says constructor PezDispenser in
class PezDispenser cannot be applied to
2:44
the given types.
2:48
So it required a string,
but it found no arguments.
2:49
Actual formal argument links differ,
right,
2:52
because we specified
that we needed a name.
2:55
And the reason why it worked before is
because if no constructors are defined,
2:58
a default constructor that takes no
parameters is automatically assumed.
3:02
However, once at least one
constructor is defined,
3:07
like we just did, you must use one of
those explicitly defined constructors.
3:10
Okay, so let's do that,
let's let's push one in.
3:15
So let's fill out this with Donatello,
3:18
my favorite hero in a half shell,
and see if it works.
3:22
So let's run that again.
3:26
There he is.
3:30
All right, let's switch this back to Yoda,
and save it, and we can run it.
3:31
Excellent.
3:41
All right, so
let's walk this one more time.
3:42
So what we've done is we've
declared a constructor, and
3:44
we know it's a constructor because
it has the same name as the class.
3:48
And we've required users to pass
in a string argument for name.
3:53
And so they pass that in and
it comes in here,
4:00
it sets the character name,
which is this private field here.
4:02
Now when I did this originally,
I cheated a little bit, and
4:05
I made the parameter name a little bit
different than what was passed in.
4:09
Now I did this to avoid what is known
as a naming collision because I
4:13
was afraid of the confusion
that it might have introduced.
4:17
But as a wise Yoda would tell us,
fear leads to anger.
4:20
So let's deal with the problem.
4:24
So really this parameter should
be CharacterName, right?
4:25
I mean, people who look at our code might
actually get angry because they wonder
4:31
what name means, especially when we have
a getter that gets the character name,
4:35
right.
4:40
It would be unclear what this was
asking for if it still said name.
4:42
So we've renamed it, but
this brings up a weird problem, right?
4:45
So the variable that comes in here called
CharacterName, let's just go ahead and
4:49
switch this too, these variables
now called CharacterName but
4:54
we already have something in our
scope called character name, right.
4:58
So how do we know which one
of these it's talking about?
5:03
There is a way to be more explicit.
5:06
Inside of a method's body, or
5:10
constructor's body,
you can use the keyword this.
5:12
So now this is talking
about this instance.
5:15
That's what this means, so
5:18
this.characterName is talking
about this character name.
5:20
This.characterName is
the private field and
5:23
CharacterName here that's outside
of it is just called CharacterName.
5:26
Now, this exact fear of confusion
around naming collision is not new and
5:30
there have been many attempts at trying
to be more explicit because of it.
5:34
There was at one time
a very popular style of
5:38
prefixing your private member
variables with a lower case m.
5:40
So what we would actually name or
variable would be something like this.
5:45
And this is popular in
Android programming so
5:49
mCharacterName would look like this,
right.
5:53
So in that saying this
is a member of variable.
5:55
And what that allows you to do is then
change this to be mCharacterName and
5:57
then change this getter
here to say mCharacterName.
6:03
So it's very clear that you're talking
about these private member variables.
6:07
So this is a common yet
different enough solution
6:13
that it gives me a chance to bring up
a new point which is one of coding style.
6:16
Now companies often settle on a coding
style for projects, and you should always
6:20
follow what is in place, no matter
if you believe differently or not.
6:23
You can definitely try to
make your point heard, but
6:27
always code in the style of what's
been determined by your team.
6:30
So if somebody is using this
in prefix style of coding,
6:33
you should follow that and
you can see how clear it is.
6:35
Now I'm sure that there are people who
would definitely disagree quite loudly
6:38
with this coding style.
6:43
And as you've seen
the problem can actually be
6:44
solved by using language
constructs of this keyword.
6:47
So there's very little suffering because
we dealt with this fear initially.
6:51
Now let's lean on everybody's favorite
editor tool and get this backed out.
6:55
I'm going to use Command Z, and you'll see
that it will start undoing what I've done.
6:59
So let's get this back.
7:03
So there's this.characterName and
boom, now we're back to there.
7:04
Now we should be all set with
our Yoda approved constructor.
7:09
There we go.
7:12
>> Awesome, so now we've made it so
7:14
a Pez dispenser cannot be created without
specifying which character it is.
7:16
And, after it's created,
we haven't exposed anyway to change it.
7:21
So we're pretty safe from the character
changing at all after it's been created.
7:25
Now I say pretty safe
because as long as it's just
7:30
us in control of our class file source
code, if we don't create a method
7:34
that allows us to change
the character name, it won't change.
7:37
But we very well could be
working with a team or,
7:41
like I said earlier, maybe we'll
forget that specific business case of
7:44
character heads don't
change after creation.
7:48
We can actually make things
even more specific so
7:51
that you can't change it even
within the same class definition.
7:55
Let's do that right
after this quick break.
7:58
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up