 Welcome to Intro to Java Classes in OOP Part 2 for Beginners. This is a continuation of Part 1, so if you haven't seen that, please go back and watch that first and we'll move on to this one. So the coding concepts today we're going to cover are the two-string method, something called scope and static attributes and static methods. So basically a quick review here, we created a person class. It's got two private attributes, a string called name and an int called age. We've got one, two, three different constructors with different signatures. So this constructor is like what we refer to as a default constructor, there's nothing there. We have this constructor which takes a string, in this case of course the name, and we have a constructor that takes the name and the age. So string and int is the signature there and assigns it when we create it. Then we have some behaviors. For this one, we've only done sets and gets, so set name, get name, set age and get age. Then over here we've got a file called person runner, and you can see I've tried all three different kinds of constructors. And so for Bob, because Bob didn't have any attributes set, we set both of those using the setters. And then Susan, of course, we created straight from the bat with a name and an age. And then Jason, we started with just a name and then we added the age. And here we printed out those attributes. So again, if you haven't seen part one, please go watch that, explains everything you see here. And now I'm going to pick up at this spot. So as I said, the first coding concept is something called the two string method. And this is a special method of Java. So before I get to that, let's go ahead and add one line here. Actually I'm going to add a couple lines. System.out.println, Bob. And I'm going to just go ahead and copy that. Oops. I've, sorry, I changed keyboards and like, I changed keyboards and I keep doing the wrong thing here. And now I'm back there. So let's try it again. System.out.println and Bob. And this is what happens when you switch from Mac to Linux, I guess, in this case. So we have Bob, Sue, and Jason. Now note here, Bob, Sue, and Jason, they're not strings. They're not ints. They are person objects. Or we could say they are instances of the person class. So what do you think is going to be printed when we print Bob, Sue, or Jason? Now you're probably thinking, well, we'll print the name. There's no reason for it to do that, but that's probably what a normal person might think. Let's go ahead and compile that. And I'm going to run it. And you'll see here, you see person at f6f4d33, et cetera, et cetera. You see person at blah, blah, blah. And person at blah, blah, blah. Now person, I think it's pretty clear, refers to the fact that these are objects, instances of the person class. That's kind of obvious. The f6 part here, these are memory locations. So this is where these objects are actually stored in the virtual memory for this particular process. So not very helpful, interesting, but not very helpful. So when we create a class and we print it, we get to choose how we want it to be printed. And that is what the two string method does. So I'm going to go over here to my class. I'm going to add a new behavior, and it's going to be public, because we want to be able to access it from a different class. Again, if you don't know what public means, go back and watch the first video. And it returns a string, and it's called two string. And so what we have to do is return whatever way we want this to be printed. I'm just going to do something very simple. I'm just going to do this.name plus, I'll just put a colon there, plus this.h. So I'm going to go ahead and save that, compile it, compile it successfully. And just as a writer, we're not printing here. There's no system.out.println or anything here. We are returning the string that we want to, in this case we're going to print it, but we could do other things with it if we wanted to. So I'm going to go back to my person runner, just compile it just to be safe. And I'm going to run it. And now you can see instead of printing out person at a memory location, it prints out, in this case, Robert25, Susan30 and Jason40, which is the format of this particular string. So that is the two string method. So when we want to use the print method with an object, we can define how that is printed, which is pretty cool. It's pretty powerful. So that's that. Our next concept is scope. Scope refers to where a variable or an object, I guess, in some cases, can be accessed. I'm not going to talk a lot about it, but just give you a little bit of an idea. Hopefully when you studied methods previously, you learned about this. So if I go back to my code here, and I go to person.java. And so what I'm going to do is I'm going to go ahead and make a quick change to my set name method. So instead of string name, I'm going to put n here. And then I'm going to put n here. Now the computer doesn't care that I did that. And I could, now that there's not name, name, name, I could delete this, but I'll just leave it there. Still can illustrate the point. Okay, so what happens is when I do set name, I'm sure if I even have it, I do have set name, so set name Robert. So Robert gets sent over to n. And this name as the attribute of the class, or in that instance of the class, I should say, is assigned to n. So the question is what happens to this n? Now some of my students, what I've seen in the past, and this is totally normal for a beginner to do, have done something like this. They either put return this.n or they put return n. Now let's go ahead and compile that, try to compile it. You'll see you get an error. It's hard to read, I know, because of the color scheme here. But it says error cannot find symbol. And there's a little career point to the dot here. And it tells you basically the n from here on doesn't know what that n is. You can't even compile it. So we know that there's something wrong. And the reason is that that n is limited to this method. So when I call this method, and then the method ends, this n disappears. The scope of n is local to this particular method. It can't be accessed outside of these two braces. Now up here, notice that name and age are defined, or I should say instantiated, use the right terminology here, inside the class. Not inside the person constructor, not inside this person constructor, et cetera, et cetera. They're not defined in the parentheses of a method or a function call. So they are available to any instance of the person class in their private. So we can't access them from outside. That's why we use the setters and the getters. So let's go ahead and put this back to name. But basically that's scope. There's, of course, more to it. But that's the important part, at least for our purposes for this particular video. So if this was in and didn't match one of these things up here, one of these attributes, it's only going to be local. It only exists while this method is running. So now the reason for that is that, the main reason for that, I guess, is a memory issue. If every time you called a method the value stayed in memory, sooner or later your memory is going to overflow your space. So once the execution reaches the end of this method, the memory for this variable, this local variable is erased. It's freed up to be used by other parts of the program. So go ahead and compile that. Make sure we put everything back the way it was supposed to be. So that was scope. So let's go back and take a look at our next concept, static attributes. And I'll combine that with static methods. You've probably seen this type of thing before. So for example, I know my students have seen the math class. So for example, so system.out.print.math.pow2.0, 3.0, oops, I forgot the parenthesis. And we'll save that, I'm going to go ahead and compile it and run that. You can see we get 8.0 because 2 to the third power is 8, 2 times 2 times 2. So notice this M is capitalized because this is coming from what's called the math class. The math class has a method called power, or POW, which takes two arguments, a double and another double, and returns a double. So notice we did not have to do something like this. So math equals new math. We didn't create an object. What we're doing, and then in that case, this would be M. What we're doing is we're calling static methods of the math class. So we don't have to create an object in this case. We're just using the class directly. There's a little copy out to that, which I'll get to in a minute. So probably you've seen something like this before. Now you've got system.out.printlin, basically the same concept. But for our purposes, while we're writing some classes, I'm going to go ahead and make a static attribute. And I'm going to call this, I'm going to make it private. And now I'm going to say it is static. And then I can int and I'm going to call it count. And what I want to do in this case, I want to set this equal to zero. So I've got a private static integer called count. So what I'm going to do is I'm just going to go ahead and put this in here quick. I'm going to say system.out.println, count. Now this is going to work because I'm inside the person class and I'm accessing this method because I think it's going to work. I might get an error. We'll see what happens. So let's go ahead and run it. Let's see if it pops up. And you see this zero here. So this zero is this count. So when I call the constructor, when I create the object, it printed count. Now here's where it gets kind of interesting. And this is the difference between static and non-static. Name and age belong to each of these instances. So Bob has his own name and his own age. Sue has her own name and her own age. Jason has his own name and his own age. So Bob's name is different to Sue's name, which is different to Jason's name. And of course they have ages that are different. Now you can have two people with the same name, of course. But hopefully that makes a little bit of sense. On the other hand, static attributes belong to the class. Let me say that one more time. Static attributes and methods, you'll see in a minute, belong to the class. So there is one count for this entire class. Bob doesn't have a separate count to Sue or a separate count to Jason. They all have the same count as part of the person class. So what I'm going to do is in my constructor, I'm going to do count plus plus, count plus plus, and count plus plus. And then if I compile it, I'm just going to make sure it compiles good. Now of course if I run this over here, nothing's going to change. It's not going to do anything. Because there's no way to, I haven't printed it. Now, because this is private, I can't access it over here. Like what I do, system.out.println, count plus person.count, can you see what I did there? Now this is going to give us an error. So I'm going to run this. I'm going to say, count has private access in person. So it's telling us we can't do that. So let me just switch this over to public real quick and show you what happens here. I'm going to recompile it. I'm going to go over to here again. And I'm going to run this. Oh, I got to compile it, sorry. I'm going to compile it, then I'm going to run it. And now you see count equals three. Isn't that interesting? And count equals three because I've created three different instances of the person object. So remember, when an object is created, the related constructor is called. So this constructor adds one to count, this constructor adds one to count, and this constructor adds one to count. So because I've created three objects, count is now three. So notice how I did this. I did person, so it's the class name, dot count, because this static attribute belongs to the class itself. Very interesting, isn't it? Now it kind of makes sense, I'm sure, at least I hope. So just like before, though, generally speaking, we want to avoid using public attributes. We don't have to, but we're going to in this case. So I'm going to change this to private. Now, think about this. How am I going to deal with this? Drum roll. I'm going to do the exact same thing I did with my setters and getters. Now in this case, I don't want to use a setter because I'm just keeping track of how many objects were created. I'm just going to make a getter here. So I'm going to say public, static note. Static goes right after public, int, I'm going to call this getCount. And you might see other variations of this, but getCount makes sense to me. So I'm going to return, now I have two choices. I can do count or I could do person, I think I could do person dot count like that, but we'll just return count. And I'm going to go ahead and try and compile that. Okay, so that worked. And then if I go back to person runner, I can do person dot getCount. Again, I did that because this is public. This is private, so I can't access it directly outside the class. So I'm going to go ahead and compile that and run it. And you can see I still got count three. So that's pretty much how static attributes and static methods work. There's more to it than that, but that's the gist of it. Now let me try one thing here. Let's get rid of that. Let's say I forgot to do that. I don't know if it's going to make a difference or not. I can't remember. Let's find out. Can we compile that? No, we cannot. Okay, so I thought it was going to happen. So you'll see error. Non-static method getCount cannot be referenced from a static context. So count person dot getCount. So non-static method cannot be referenced from a static context. Now the static context is the person class. And getCount is now non-static. Because we got rid of the static keyword there. So now if this was private int count, it would work. But then it would be different for each of those objects. So static methods should be used with static attributes. So we're going to recompile that. Go back to here. Recompile that. And run it. So that kind of makes sense. Now here's the one that's probably going to kind of confuse people because I find it confusing. What do you think is going to happen if I do this? Bob dot getCount. Person's the class. Bob is an instance of the class. GetCount is a static method of the class. And it references a static attribute of the class. So let's go ahead and compile it. It compiled. I guess that's a good sign. Let's go ahead and run it. And you can see it gives me the same result. So I can go ahead and copy this. I can do Bob, Sue, and Jason. GetCount, getCount, getCount. So I run it. And you can see it, they all have the same value. So this is where it's just a little bit weird. Like, I think this part makes sense. So static attributes and static methods can be accessed from using the class name. It kind of makes sense. But they can also be accessed using an instance. So Bob getCount will call this static method. And it will return the count that is common to this class. Now if I do the opposite, if I do person.getName. So static, non-static. Let's compile that. I get an error. So non-static method cannot be referenced from a static context. So this is static, non-static. So getCount. So static, static, okay. This is non-static. Instances are not considered static. GetCount is static. So I can do non-static, static does work. And it kind of makes sense. The class itself can't access individual instances because they were kind of created over here. Kind of makes sense. But instances of the class can access static attributes and static methods of its originating class. Et voila. Pretty cool stuff. A little confusing. But once you get used to it, it's not too bad. Again, how I usually explain this to my students is if it's static, it belongs to the class. So that means static attributes and static methods. However, static attributes can be accessed from this context, from one of these, or static, I should say static methods. I'm not sure what I said there. Can be accessed from instances, which is pretty cool. Yeah, that's it. There's probably a few other little caveats about this. Let's see here. I'm kind of curious if I can update this. Let me just try this. I'm not sure what's going to happen. So a lot of these things I have to check every once in a while myself. Okay, it worked. Okay, so it does work. So I can access that inside here. So that's pretty cool. So you can access static from non-static. Okay, from non-static from here. But you can't access non-static from static. Okay, so that's the rule that you need to go with. So that is that. So today we learned about the two-string method, scope, static attributes, and static methods. So thanks for watching. I hope this helps more than it hurts. I'm Tokyo EdTech. Keep on coding.