As we saw the public prefix, or the access modifier as it's called, on our fields of our Person class, allow us to determine whether or not outside classes can see them and therefore whether or not they can access them, change them, read them, see their values, and so on. Now, there's more than just public, of course. There's also private. We can call these fields private instead of public, so let me take out Name from public accessibility, make it private. Now, when I go to PersonFactory that references that field... Just do this again, just so you see. It is taking a little while. There you go. You don't even see the field available in IntelliSense. Took a little while for Visual Studio to clue in that Name is inaccessible due to its protection level. You see that there in the error list, right? We can call a field private when we don't want or don't need outside classes to see that field. Or a method, same thing applies to methods. Public and private, pretty easy to understand. There's also other accessibility, access modifiers available. There's one called internal, and another one called protected. Now, we won't really go into those right now, and as a matter of fact, you probably won't even be using those throughout this course, but they do exist and they are not that hard to understand, but they are not really useful for us to look at the moment.
I want to also quickly mention that you may have remembered in our original prototype game demo that we used the public prefix in some of our classes, like for example the CubeController, we made cool counter CoolCounter We made it public in that case, not so that classes we're writing can have access to it, but just so that it became available to our inspector, so we can see CoolCounter there in our inspector. That was the only reason we did that, but right now I am just mentioning that kind of in passing. Right now I just want to concentrate on the C# fundamentals of instantiation of our objects and so on, and not worry too much about mixing that up with Unity itself, so what I want to show you right now is a really cool aspect of being able to create our objects off of our class blueprints, so here we have this person we created. Just for the purposes of making this more readable, change all these references to person1 first. And let's do this ... Type in "Person." Call this variable person2, person2 = new Person() and pretty much do the same thing as we did before, but with different values, because each object of type person is going to be different, right? Just like in the real world. That is person2.Name. That's the Gender, just like before, but different, because it is a different person, and we'll want to output that as well, just like we did with our Mario, person1, and change that reference, just to go quicker, to person2, so we are going to output that as well to Unity and see the result.
Going back to the console, and no surprise ... There you go, we have Mario, Male 26, and Peach, Female 17. So, as you can see by encapsulating our code into classes, we get a lot of the same kind of code reuse we get with methods. A method definition can be referenced over and over again to run that same code block, whereas a class definition can be used to create many objects with the same or slightly different values, so we can make more than one person off of the Person class blueprint. As mentioned previously, we can also include behaviors and processes that are common to all objects in our class, if we feel that behavior is somehow important to our program. So, let's demonstrate that by creating a simple process we're all familiar with called aging. Let's represent that programmatically in our Person class by typing in that process. Let's do this ... public void, call it DoAging(), and simply increment the age with the ++ as we saw before. That just increments it by 1. Now we can go back to our PersonFactory, and after we have our two different person objects, we can run that method for each one of those persons. People, I know. I just said persons just to not confuse. person1 runs its DoAging() aging method, and person2 runs its DoAging() method, and then let's see the result of that method by outputting each person's Age.
There we go. We incremented Mario's Age from 26 to 27 and we incremented Peach's Age to 18, and we can run these methods over and over again, as many times as we want, and we will have this sort of simulated aging process being done on our person objects. Something you may have noticed is that we are using our Person class like it is a type. When we establish the class name there, it looks like any other variable type, right? That's because it is a type. Our basic definition of a class as a container has evolved to a much more interesting programming concept. It is now elevated to that of a user-defined type that is just as much of a type as pre-defined types we have already come to work with, bool, int, etc. person1, Mario and person2, Peach are not of type string or int. They're of type person, so given that when you're creating a class, you're actually creating user-defined type, a type that is ... Can be used just like any variable type we've been working with thus far. It gives rise to all sorts of interesting possibilities and complex containment structures such as ...
In the next video, we'll look at how to create a field, which is of a type that is of an outside class, creating a really interesting relationship... A containment relationship between those two classes, so I understand it's really heady stuff at this point maybe, but I have all the confidence in the world that you'll be able to wrap your head around it. You're doing great so far. I'll see you in the next video. Thanks.
Lesson 19 - OOP, Access Modifiers, Instantiation