Constructors8:00 with Craig Dennis
Let's learn about constructors to require information at object creation time.
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 up