TheJach.com

Jach's personal blog

(Largely containing a mind-dump to myselves: past, present, and future)
Current favorite quote: "Supposedly smart people are weirdly ignorant of Bayes' Rule." William B Vogt, 2010

Introductory Object Oriented Programming

This is meant for a beginning student of any programming language that has a concept of functions and variables. If you can understand the following pseudo-code (which is fairly math-influenced):

f(x) = x*x

let a = f(3)
let b = a + 1 // b is now 10.


or even if you just have the basic notion of functions and variables in your head, you're ready to read this. (A brief refresher anyway: in general, functions are data structures which receive input and return output. Variables can be set up to receive the values of the input and output.)

What is Object Oriented Programming (OOP) all about, anyway, and why is it useful? On a very abstract level, it's about the Real World and makes programming seem more similar to things you do in every-day life. It's useful for that specific reason. OOP is intuitive, it mimics how things really are to us. On a slightly less abstract level, OOP is about multiple, independent, and 'intelligent' agents. Let's go over these terms using real-world objects.

In my left hand, I hold an apple. In my right hand, I hold another apple. There are two apples, therefore there are multiple apples. Are they the same apple? If that were true, then I would expect that after I took a bite out of my left apple, a bite would magically be taken out of the right apple as well. This is not true, however, so we say the apples are independent.

What's an intelligent agent? It's anything we can personify mind-like attributes to. Let's pretend our apples have brains and a mouth--I can ask the one on my left "What color are you?" and it might reply "Why, I'm red of course!" I could ask the same question to the apple on my right, and it might reply "Why, I'm green of course!" I have personified the apples in such a way that they behave like people; I can ask them questions, and depending on how smart they are, they can answer my questions. (I think it would be overestimating the intelligence of an apple to ask it to solve for x in a right triangle.)

So, OOP is about "multiple, independent, and intelligent agents". It's useful because it mimics how we like to think about the real world. Of course we know apples can't talk, but wouldn't it be so useful if they could? It would be so useful if I could just ask an apple seed "What kind of apple will you grow up to be?" It is this usefulness that we wish was reality which OOP captures.

The question of "What is an Object?" should be slightly clearer by now. An Object is an independent intelligent agent. If this is not clear yet, please go back and reread until it is.

Now it is time to get a little less abstract as we try to further define the essence of an Object. We know what we want on the high level (multiple independent intelligent agents), but how might we do this with a computer that works with functions and variables? What is it these Objects are supposed to be able to do? There are three key terms: message passing, local state, and inheritance. Let's again define these terms.

Message passing is what it says. If I have an apple Object, I can send it a message in the form of a question: "What color are you?" However (and this will be important soon), I don't speak fluent AppleSpeak, so it would be wise of me to pass this message to a translator who will ask the apple Object on my behalf. The verb "passing" is key, here. If I'm talking to the apple, either directly or indirectly, I'm really just sending it messages. But because I don't speak AppleSpeak, I need my message passed along through something that does.

Local state is a fancy way of saying independent. Why repeat it? Well, we're at a slightly lower level of abstraction remember. Local state pertains to everything you can say about some apple Object. Its color is some fact about it, and I might change that color by dipping it in dirty oil, but I should expect that action to not change any other apple Objects I might have with me. To make the point clearer, perhaps, let's take a brief dip into an even lower-level of abstraction. An apple's "color" is a variable specific to that apple alone. If I modify it, I can expect the state (value) of that variable to be local (with respect to this apple Object) only.

Inheritance is one of the most powerful ideas about OOP, and indeed nature. Consider yourself: you had exactly two parents, and your genes are a mixture of the two, but you share very similar attributes with your parents. If both of your parents have brown eyes, chances are you also have brown eyes. If both your parents have the emotion "happiness", chances are you also have the emotion "happiness". Humans are very complex creatures, and it would be horribly inefficient and error-prone if parents had to explicitly state every single attribute they wanted their children to have. It's far easier to say "Be just like me, except 2 inches shorter and a little smarter" compared to "I want you to have this, this, this, this, ..., and this" and finding out you forgot to give your child empathy.

This is the concept of inheritance. Just as you inherited many attributes from your parents, thus an Object can inherit many attributes from its parent(s). Note the parenthetical 's': in programming, we're not limited by biology to having exactly two parents. We may have one, or ten. We may also have zero or more grandparents, and we may have zero or more children. OOP is more flexible than reality in this way.

What is an Object, and what does it support? An Object is an independent intelligent agent, and it supports message passing, local states, and inheritance. If this is not obvious to you, please reread above before continuing, as we're about to jump yet another level down the tower of abstraction.

We're down at the level of actual code now. How is this supposed to work? What must our programming language support for us to do OOP? Again there are just three components; these are functions which encapsulate the above ideas into a structured syntax. The functions are: define_class(), instantiate(), and ask().

There is some new terminology here. What is this "class", and what does the verb "instantiate" mean? A class can be equated to a template for your Objects. It is the blueprint. If I'm an architect and I want to build a couple of identical buildings, I don't rewrite the blueprint for each one, I just use the single blueprint. The blueprint for the building is the Building Class, and each actual building I construct is a building Object. The template might define things like how many windows there are, or a way to add and remove stories to the building. This gives us some flexibility with the Objects. If I make a building in New York from these blueprints, it might be 200 stories high and have 2,000 windows. But I might also make a building in Seattle, using the same blueprints, but now the only difference from the one in New York is that this building has 50 stories and 500 windows.

The verb "instantiate" means "to create an instance of." In the context of OOP, we're creating instances of classes. In order to create a building, I must create a building Object. Because each Object is independent and there may be multiple ones, I can't just equate it with the blueprints of the class: I must instantiate it out of the class.

If the concepts of what it means to create a class and what it means to create an Object of that class by creating an instance of that class are not clear, then again, please reread until it is. If you're good to go, put on your programming caps, since now we're going to technically discuss the three functions.

define_class() creates a class, or a template, to use in your code, and it behaves like a function itself. For simplicity's sake, we'll say it only takes one argument: the class name. An apple class might look like this:

define_class(apple) {

color = "red";

method(what_color?) {
return "I am the color: " + color;
}
}


This pseudo-code probably doesn't match what you've seen in your language if you have prior OOP experience; that's okay, I'm going to explain it. Do you see what define_class() is doing? Its argument is a word which is the class name. Inside of the curly braces is the class implementation, or the actual substance of the blueprints. Inside we have a local variable named color, set to a value of red in quotes, and something called a method. A method is a special type of function that exists only within a class or Object; the method() function works like define_class() in that its argument is the method name, and inside its curly braces is the implementation of it. Methods are the brains of your Object. In order to ask an apple what color it is, the apple must have a method to process that question. If you want to ask more questions, add more methods.

Once the above code is run, we now have an apple class to work with. Let's make some objects.

instantiate() creates an instance of a class and returns an Object. It takes one argument: the class name. So some pseudo-code for that is this:

left_apple = instantiate(apple);

right_apple = instantiate(apple);


We now have two apple Objects: one on the left and one on the right. These objects are separate from each other, but they are both apples and both behave like apples. Let's ask them a question.

ask() sends a message to a given Object, and returns whatever the Object responds with. It takes two arguments: the object, and the message. You as a programmer pass a message to this function, which does the sending--remember, you don't speak AppleSpeak. Let's check this out:

left_color = ask(left_apple, "what_color?");

print(left_color);


This pseudo-code will display to the screen the words "I am the color: red". Notice how our message is in quotes? That's our English. The ask() function takes our English and converts it to AppleSpeak, asks the apple Object the question now, takes the response, converts it back to English, and returns it into our left_color variable.

That's all there is to OOP in a nutshell. If you want to do inheritance, use a function called parent() inside the class definition to specify. (Unfortunately, useful examples of inheritance are typically complicated. See below for a semi-useful one, though.) If you know the apple class has a variable called 'color' in it, you can just ask for that variable directly with ask(apple_object, "color").

As a beginner to OOP, you're done with this tutorial, and you're ready to learn the actual syntax of your language of choice to do all this, along with things that are not immediately obvious from this. As a benefit for more advanced readers, however, the following short section goes over a few other things you might have heard about OOP, and how the syntax defers in the pseudo-code from a language like Java. If you're just beginning then again, you're done, and thank you for reading this.


First of all, here's an example of inheritance:

define_class(EnemyCharacter) {

health = 20;
attack_power = 30;

method(attack) {
return "I attack with power " + attack_power;
}
}

define_class(Tank) {
parent(EnemyCharacter);
health = 40;
}


The first class is a generic EnemyCharacter template. Enemy characters all have health, all have attack power, and they all have the ability to attack. I could make a generic enemy Object that is instantiated from the EnemyCharacter class, and I could say: ask(enemy, "attack") to ask it to attack, and it will respond with a message indicating its attack power.

The power of inheritance is that I can make a tank Object from the Tank class, and because its parent is the EnemyCharacter it shares all attributes with the EnemyCharacter class. If I want to change something, I do it after calling parent(). In this case, the only thing different is a higher health. Now even though I didn't specify the method "attack" anywhere in the Tank's class definition, it still knows what an attack is thanks to its parent. Thus I can ask(tank, "attack") and it will respond just like an enemy would. This is the power, but I apologize I can't give a more thorough example. Look at actual source code for large projects for (potentially) good examples.

In other classes you might have heard that OOP is about these three things: encapsulation, inheritance, and polymorphism (there is sometimes even a fourth thing called composition added on later). Encapsulation is the same idea as local state, and polymorphism and inheritance go hand-in-hand so it's simpler to just refer to inheritance. This concept of message passing is key, I think, and it's too often skipped over. Message passing is at the heart of all OOP. In Java, an apple class and object would look totally different from the above pseudo-code, but the concepts are all there.

// apples.java

public class apples {
public static void main(String args[]) {
Apple left_apple = new Apple();
Apple right_apple = new Apple();

String left_color = left_apple.what_color();
String explicit_left_color = left_apple.color;

System.out.println(left_color);
System.out.println(explicit_left_color);
}
}

class Apple {
public String color;

public Apple() {
color = "red";
}

public String what_color() {
return "I am the color: " + color;
}
}


So much uglier... Anyway. The define_class() function is abstracted into the "class" keyword. If you want to have inheritance, then you use the keyword "extends". (Java unfortunately doesn't support multiple inheritance.) The instantiate() function is abstracted into the keyword "new". The ask() function isn't so obvious, though--it's the dot operator. object.method() is the same as ask(object, "method").

As you see, most OOP languages nowadays hide the actual functional nature of OOP by using keywords. But I think knowing this functional nature is very important to understanding what OOP actually is, and if you're further advanced, how you might implement it from a language that doesn't natively support OOP via keywords.

[This post is released of all no-derivative rights. Meaning you can use it in its entirety or in parts or to create your own reference with no restrictions.]


Posted on 2009-09-12 by Jach

Tags: programming

Permalink: https://www.thejach.com/view/id/27

Trackback URL: https://www.thejach.com/view/2009/9/introductory_object_oriented_programming

Back to the top

Back to the first comment

Comment using the form below

(Only if you want to be notified of further responses, never displayed.)

Your Comment:

LaTeX allowed in comments, use $$\$\$...\$\$$$ to wrap inline and $$[math]...[/math]$$ to wrap blocks.