From zero to Object Oriented Programming, an introduction.

Just like water is a great analogue for electricity in regards to some of its behavior, animals too can be used to explain in simple terms concepts like object oriented programming.

Generic dog Dogs, a class of animal

Following this line let’s pick dogs, but not just any particular dog, just dogs in general as a species. A dog is a type of animal with certain specific attributes (amount of legs, color, size) that are common to all dogs, even if the value of those attributes vary a bit for each member of the species. All dogs also do things (actions) that are common for the species, such as barking, playing, running.

Will use two well know dogs for this example: The asian cousine loving Paco’s Bell chihuahua dog and the crime fighting Rough Collie known as Gassy, forgetting for a moment that both dogs are of different breeds and focusing on the simple fact that both are members of the animal species known as dog.

Moving now to the computer world and using the vocabulary for OOP (object oriented programming) we can say that dog is a class (type) with certain properties (attributes) and methods (actions). On that same line we can say that the Paco’s Bell dog and Gassy are instances of the class dog. All computer languages are different but I’m going to provide some code examples using a made up a language which should correlated to actual languages’ constructs.

Let’s define a dog class:

class Dog:

Some languages require classes to be capitalized others don’t. Capitalization is used to indicate the importance of the class in regards to other identifiers such as variable identifiers because classes are not variables. Notice how I said define and not create a class, while both are synonyms and can be used interchangeably, “define” is more closely related to what a class actually does. A class by itself doesn’t create a real dog, a class is a definition or a template from which actual members of its type are created or instantiated.

So now let’s actually create two real dogs from the class Dog:

dog1 = new Dog()
dog2 = new Dog()

We call the language command with the Dog class as argument for this example, but in other languages you just execute the class, and its result is a new independent member of the Dog class or what we established is called an instance. The resulting instance can be stored in a common variable. We can say that the variables dog1 and dog2 hold one separate instance of Dog respectively. If this sounds very coherent in English, it’s on purpose. Computing terms are usually picked from the English language for their meaning in an effort to make the term convey such meaning in the computing world more intuitively. Since classes are definitions and not an actual instances by themselves, a class doesn’t have a specific identity, the instances are the ones that have identity. That is why the class Dog cannot be called Gassy but an instance of Dog can be called Gassy. Name is just one of the properties a Dog can have that vary from one instance to another. Let’s define a Dog class again that also includes the definition of some properties:

class Dog:
    property hair_color
    property height
    property name

Each property is defined but no value is assigned because we still aren’t creating any instances of Dog, (remember classes are templates) so we cannot know beforehand what color a new dog will be. If we know the typical value of a property we can specify a default value for a property that any new instance of Dog will inherit when it is created. Let’s create some new instances of Dog each with new properties, and update the properties of each instance to a specific value.

dog1 = new Dog()
dog1.hair_color = "Ochre"
dog1.height = "Small"
dog1.name = "Pedro"

dog2 = new Dog()
dog2.hair_color = "Calico"
dog2.height = "Medium"
dog2.name = "Gassy"

Chihuahua dog The paco’s bell dog is an instance of an animal type named dog.

Every instance of a Dog is independent of each other, changing a property in dog1 doesn’t modify anything in dog2. Just as we set a property to a specific value we can also retrieve the value of a property. Once again language conventions vary but it is common to use a dot behind the variable to indicate we are referring to a property of the instance, for the purpose of setting the value or getting the value. When you have the ability to access the property of an instance directly it is said that such property is public.

Classes can also define private properties than can only be accessed from other parts of the class itself. This is useful when you want to store a value that should not be modified directly, such as the result of a computation or a state (running, jumping, resting, on, off). But if a property is private and cannot be accessed directly, how can we get (read) or set (write) it’s value?

Earlier we mentioned that all dogs had a specific set of properties (attributes) and can do certain actions that are common to all dogs. In OOP, actions that are typical for a class are called methods. A class defines methods which we execute or in OOP terms we "call". Since a class is a template, a definition, we don’t call methods in relation to the class, we call methods in relation to the instances. Methods is also the mechanism we use to get access to private properties. Let’s expand the Dog class definition to include some methods:

class Dog:
    property hair_color
    property height
    property name
    private property thoughts

    def bark(self):
        display "bark!!!"

    def sleep(self):
        self.thoughts = "bacon"

    def wakeup(self):
        self.thoughts = "play"

    def mythoughts(self):
        display self.thoughts

This class definition adds a new property: "thoughts", which is private and cannot be changed or read from the "outside". Four methods were also added: bark, sleep, wakeup, and mythoughts. Another concept introduced is: self, which will become clearer when we instanciate two dogs from this class.

dog1 = new Dog()
    dog1.hair_color = "Ochre"
    dog1.height = "Small"
    dog1.name = "Pedro"

dog2 = new Dog()
    dog2.hair_color = "Calico"
    dog2.height = "Medium"
    dog2.name = "Gassy"

Once again we create two dog instances. Let’s make the first dog bark:

dog1.bark()
(Computer output) > bark!!!

easy enought, right? Now let's modify dog1's state of mind by making it go to sleep:

dog1.sleep()

Collie dog Gassy, a rough collie with the independent callico hair color property that likes to dream of bacon

We just called the method sleep, which was defined in the Dog class and since we called it from the dog1 instance using the dot notation it will only affect dog1 properties, since each dog is independent and changes in once doesn’t affect others. This is where the self concept come into play. From the programming stand point when we are defining the sleep method, we are defining it in the class, no dogs based on this class exists yet, so how do we tell our code which dog instance's properties we want to access? We use self. Self is a special variable that will always refer to the instance that is calling a method. Some languages call this special variable this. When we call the sleep method, the variable self is equal to dog1, that way we can refer to an instance’s own properties before the instance even exists. If we were to call the sleep method on dog2, during the execution of that method, self would be equal to dog2, but only during that execution. The variable self, like anything else in every instance is independent, so just like two dogs can have the same property named name at the same time and the values of the name property for each dog be different, so can the variable self exist for each dog without conflict.

Let's see what dog1 is thinking about. Since thoughts is a private property and cannot be accessed directly, the Dog class provides us with a method to reach into the private property and see it’s value.

dog1.mythoughts()
(Computer output)> bacon

let’s wake up dog1:

dog1.wakeup()
dog1.mythougts()
(Computer output)> play

What are the uses of private properties and the corresponding methods for reading and writing them? Suppose you define a class to compute an equation, with properties to hold the variable values for each iteration (instance) of the formula. Now suppose one of the variables of the formula can only be an even number. If we make that variable public, anybody would be able to set it to any value and we would have to check the value constantly to make sure is it valid and not throw an error when we want to express the equation. By making the variable that needs to be even numbered private and providing a single method to set its value, we can place a few lines of code in that method that would make sure the value is valid before even finally assigning the value to the private variable, thus eliminating the need to verify the variable every subsequent time it is going to be used. When we use specific methods to set or get a private property’s value we can say that we have defined a getter and setter for a specific property. This method of "hiding" properties and using getters and setters to modify then in a controlled manner is called an interface and ensures continued compatibility for other code or users accessing your classes and instances even when you make internal modifications to private properties as long and the interface remains unchaged. This encapsulation of internal functionality with external interfaces is just one of the many advantages that OOP provides over other programming practices. There are many other features of OOP in general and of specific languages implementations. The ones covered here just scratch the surface of what can be done when you learn and master Object Oriented Programming.

Image credits: