Think of it like one of those huge toolboxes, the kind where every compartment has a mini-toolbox inside of it. Each mini-toolbox can contain both tools and more compartments.
Say you want to glue two pieces of wood together. First you are going to go to your *toolbox*. Within the toolbox, there a few compartments: carpentry, electrical, and plumbing. *Carpentry* is the relevant compartment, so you open it. Inside are some tools that are useful for pretty much any carpentry project: hammers, levels, clamps, etc. There are also some more compartments: nails, screws, adhesive. So you open the *adhesive* compartment. Inside are several types of glue: wood glue, super glue, hot glue, etc. So for you effort, you claim the *wood glue*. But before you can use it, you need to read the *instructions.* It says mix with 50% water. So you dilute the wood glue and complete your project successfully.
In this metaphor, the *big toolbox* is equivalent to a class. It is a container that holds other containers and tools. With a caveat. The top-level container does not physically contain the lower-level containers; rather, it lists their names. The “container” is literally a file (composed by the programmer as a text file originally).
The *compartments* (carpentry, electrical, plumbing, nails, screws, glue) are akin to classes as well. Relative to the toolbox, carpentry, electrical, and plumbing are *subclasses*, and the toolbox is their *superclass*. Likewise, nails, screws, and adhesive are subclasses of carpentry. They are the containers named by the top level container. They also name the container that contains them. (In other words, the superclass lists its subclasses, and the subclasses list the superclass they are part of). Again, these containers are files.
The tools (hammers, levels, clamps, wood glue, super glue, hot glue) are akin to methods. When a method hits the command line, it makes your computer perform an action, like drawing a line across the screen, closing an application, or altering a property within an application’s memory.
The instructions are akin to properties. They do not do anything by themselves. They are just values listed in the class. However, oftentimes, these values store information that guides how the methods perform. As previously mentioned, methods can also alter properties.
For example, imagine a video game with NPCs. The NPCs can become hostile to you if you wrong them, and they will remember your transgressions even if you leave and come back later. Therefore, you need to write a method that determines how the NPCs will react to you on sight. You call this method “onSight()” and you write it inside a class called “NPC”. “onSight” is triggered when an NPC sees you, and it contains two sub methods: “greet()” and “hostile()”. “greet()” makes the NPC greet you peacefully, and “hostile()” makes the NPC attack you. But how does “onSight()” choose between the two?
onSight() needs inputs to determine how it behaves. So inside your “NPC” class you also write a boolean property called “isHostile”. Now you rewrite “onSight()” to be “onSight(isHostile)”. Now when you call “onSight(isHostile)”, the game will check whether the NPC is hostile to help it determine what action to take. By default “isHostile” is set to 0, and “onSight(0)” will result in the “greet()” method running.
However, if the player does something to anger the NPC, you can write another method that runs whose effect is to change “isHostile” from 0 to 1. Now when “onSight(isHostile)” is called, it will be “onSight(1)”, and it will ultimately run the “hostile()” method, making the NPC attack you.
But wait, you might say. The class “NPC” is a file on my computer. Does that mean I have to make a class file for every individual NPC?
The answer is no, and this is where the “objected-oriented” part comes in.
In addition to properties, your code can contain variables, which are very similar to properties. Variables all have a type. Types are things like “int”, “string”, “bool” etc.
At the end of the day, these types are classes. And there is nothing stopping you from creating a variable of your own custom class. Thus, when you want to add a new NPC to your game, you don’t need to make a new file. You just need to make a variable of the class “NPC.” Such variables are called objects.
Objects can access all the methods and properties in their own class *and* in their subclasses. They cannot access methods and properties from their superclasses. So going back to the “NPC” example, the “NPC” class might be a subclass of “Game”. “Game” probably contains methods that do things like opening the main menu or saving the game. NPCs don’t need access to these methods, so it would be wasteful to declare an NPC as an object of the “Game” class. Everything an NPC needs to be an NPC is contained within the “NPC” class and its subclasses.
On the other hand, the “Game” class needs to be able to do things like create new NPCs on the fly to attack you, so “NPC” needs to be a subclass of game.
Going back to the toolbox example, say you want to start selling this toolbox in stores, and you fabricate it en masse. You might find that it’s being bought by carpenters, electricians, and plumbers, but they all have a complaint. They don’t need 2/3 of the tools in the toolbox–it’s wasting space and money. It would be more efficient to sell the carpentry, electrical, and plumbing mini-toolboxes separately.
On the other hand, a business that employs all three kinds of tradesmen might like to buy the full toolbox. Or someone thatching their roof might only be interested in the nails.
As a final comparison, these two things would be equivalent:
>Toolbox.Carpentry.Glue.woodGlue(instructions)
>
>Main.Game.NPC.onSight(isHostile)
Latest Answers