Object Oriented Programming

Object Oriented Programming languages are defined by the following key words: abstraction, encapsulation, inheritance, and polymorphism. An object is a container of data and functions that affect the data. In an OOP, a "child" object can "extend" another object (making it more specific) by inheriting from a "parent" object. Thus the child gets all the parents data and functionality "for free". The idea of an "interface" is also key to OOPs. An interface is the allowed interactions between the outside world (e.g., other programs) and the object itself.

The following notes are "in progress". Please refer back to this page at a later date.


Objects

Objects are at heart very simple. They are a way to represent information about a "real world" idea and they contain ways to manipulate that information. All of this "code" is encapsulated in an object recipe (Class file).

  1. They contain information about something in the program.

  2. They provide actions (also called functions or methods) which manipulate that information. By combining all the data and actions that can apply to an "object" into one piece of code, we make our programs easier to write and maintain.

Often an "object" in a computer program tries to model (i.e., approximate) a real world entity. For example a "car" could be modeled in a computer by information about the size, number of doors, engine, color, etc. of a car. Additionally there would be little pieces of assocaited code (called methods) which manipulate the car, for example: start_car() would "simulate" turning the engine on, break() would simulate slowing the car down, etc.

The interface between the car object and the rest of the program (or world) would be the putlic methods which are allowed on the car. For example, turn wheel left, turn wheel right, step on gas. We don't know (nor do we care) how these function work, just so long as the car does know and responds appropriately to each function call.

Objects vs. Classes

Classes are to Objects as Recipes are to Cakes.

The class file contains the blue print (or recipe) of how to build an object and information about what defines an object.

The "object" is the computer's Run Time representation of the data describing the object and the methods to manipulate the object.

There is a strong correlation between these two items, but it is important to remember, objects exist when the program is being run; the class file is written by the programmer to allow the computer to use/construct new objects.

Note: Often we will be lazy in our English level descript and say object when we mean class, or class when we mean object. The wise student will ask for clarification if it is not immediately apparent by the context what is really meant.

Parts of an object:

For an object design pattern (in ActionScript), refer to the following Design Pattern

All Class files contain the following parts:

  1. The Package (or namespace) that the class belongs to. Packages are just a way to allow you to have a "Bank" class, and me to have a "Bank" class and thus distinguish which Bank is which.

    Often a package name will be something like: jims_code, or pacman_game_code, or graphics_utilities. The purpose of the package is to combine all related code under a single identifying ("package") name.

  2. Class Name and Inheritance information.

    The name of the class should be a symbolic representation of what the class represents. The inheritance information describes what "parent" class the object comes from. For example, a car doesn't really stand alone. A car really IS A vehicle. Likewise a truck IS A vehicle. All information that would be the same for both cars and trucks (and others) really should be placed in a Vehicle class, from which both cars and trucks extend.

  3. Data Fields (sometimes called Member Variables) representing facts about the object.

  4. Methods representing actions on the object.

    Some common methods are:

    1. Constructor
    2. Setters
    3. Getters
    4. toString
    5. create_display_list (for objects to be displayed graphically).

Fields or Member Variables (or Object Level Variables)

The goal of an object is to contain enough information to (in the program) describe (or approximate) the idea. For example, we might have a "square" object. A square can be defined by the X,Y position of it's center, and the length of its sides. This is enough information to "recreate" a square.

function vs. method

In this document you see the words function and methods. These all synonymous for each other. Java calls its functions methods. Actionscript calls its methods functions...

Member Variable vs. Object Level Variable vs Field

The variables which contain the information which define an object will be usually be referred to as member variables, but sometimes as data fields (or just fields), or as "object level" variables.

Member variables are accessible from any function in a class file. For example, in the car example, when we say turn right, the car code really needs to know lots of things, like are we moving, how fast, is the break on, etc etc etc. All of these pieces of information are stored internally to the car in member variables. Every function in a class has access to all member variables, and any change made to a member variable (e.g., changing the speed from 10 mph to 5 mph) would affect the future operation of any other function.

Public vs. Private vs. Protected

When creating objects (or just reading the code for objects created by others) you will often see the key words: public, private, and protected. Here is a short description of what they mean:


Object Functions (or Methods)

Once the data has been defined for what it means to be an object, then the programmer needs ways to manipulate that data. These ways are called functions.

An object's functions have access not only to their parameters (as all functions do) but also to ALL Member Variable!

Special Functions

There are a number of functions that have special meaning and are found in most class files. The primary example is the Constructor.

The Constructor

The constructor (for an object) is a method that is called (FOR YOU by the computer) whenever you craete a new object. The purpose of the constructor is to initialize values for all the member variables associated with the object.

In previous computer languages, objects (then called structures) were allowed to be created "empty". Empty meant: "What ever the heck happened to be in memory at the time". The developers of those languages "knew" that programmers would always initialize these objects directly after creating them... This is a great example of something that was "known" but was in fact NOT TRUE. This often created very hard to find mistakes in programs where future code accessed undefined variables.

Learning from these program language design errors, the creaters of new languages, like Java, ActionScript, and C++, developed the Constructor. The constructor is a special function that can only be used once, never returns a value, and sole responsibility is to make sure every data field in the object is intialized to a reasonable value to start.

It Cannot be overstateNo object should ever be created without valid "Data". Every object should have a constructor to initialize all of its member variables.

Default Values: In other programming languages, such as C, the default value of a variable can be what ever happens to be in the memory of the computer at the time your program is run.... This can mean that a "salary" variable could hold -9101982309812 or a "name" variable could contain "lkjasdf10983o1jrln!@#!#@FWEJKLSDJF:LSJdf".

In ActionScript (and Java for that matter), all variables default to a given value if you forget to assign them. The value is usually 0 (or NULL, which is covered under pointers/references). Even though there is a default value, always create a constructor for every object!

Here is our generic shape's default constructor:

	  
  /**
   * Generic Constructor
   * 
   * @param x - center of shape x value
   * @param y - center of shape y value
   * @param size - size (can be overwritten or dismissed by children classes)
   */
  public function Generic_Shape ( starting_x : int, starting_y : int, starting_size : int)
  {
    this.x = starting_x;
    this.y = starting_y;
    this.size = starting_size;
    
    this.color = Color.red;
	  
  }

	

Key Ideas behind the above constructor:

  1. "public"

    The public key word tells the class file (and other programmers) that this object can be created by anyone. Public means anyone. Alternatively in some cases, you will see the key word "Private" next to a function. Again, this means that only the object itself can use the function.

    Would it make sense to allow only the object itself to create the object itself?

    Think of this in the same way you think of your "door bell" and your "dishwasher". Everyone can use the door bell (its public to the world). Only you are allowed to use your dishwasher (but perhaps other people could use the clean plates that the dishwasher produces...).

  2. Parameters: (int starting_x, int starting_y, int starting_size)

    Parameters are symbolic names for the information that must be presented to the object when it is created. The information in these symbolic names, which is provided by the "caller" of the method, is used to transform a "generic" version of the object into a specific version of the object. For example, we might set the x,y of one square to 100,200, and of another square to 500,600. The parameters allow the creator of our Square object to give it a "personality"

  3. this - (the key word)

    You will often notice the use of the key word "this". "This" refers to the current object. "This" is a runtime (as well as compile time) concept. The use of "this" is not required, but is used by the programmer to show that he or she knows that the thing being referred to is an "object level function or data value).

    Local variables (those used only within a function) are not tagged with this.


Object Oriented Programming Principles

The following discussions of OOP principles will refer to a vehicle hierarchy:


                 Vehicle

              /           \ 
        
         Car             Truck

        /  \             /     \
 Station    Sedan     Pickup    18-wheeler
   Wagon

      

Encapsulation

Encapsulation, is the idea that the "data" associated with an object should (mostly) only be available via functions, and (possibly) that much of the data associated with an object will never be "visible" to the outside world.

For example, most of use do not care how our car engines work. What we do care about is that when we turn the key, the engine starts, when we press the gas, the car accelerates.

See the OO topic on Interfaces for more on Encapsulation.


Inheritance

Inheritance is the idea that a "child class" gets all the functionality of its parent class. This works because child classes are more specific examples of the parent class. For example, if we had a "vehicle" class, we could have a "car" class as a more specific example. Then we could have a "sedan" class as an even more concrete example.

	
	  public class Car extends Vehicle // CAR IS A Vehicle
	
      

It should be strongly noted that the CLASS is where inheritance is used, not the object. While we often say object car inherits from object vehicle, what we really mean is a single new class has been created in which both the car code and the vehicle code have been combined to form the car class.

ISA vs. HASA

When one class "extends" another class we say that the first class ISA (is a) second class. A car ISA vehicle. Anywhere that a vehicle can be used, a car can be used. If you can "drive" a vehicle, then you can "drive" a car. If you can "stop" a vehicle, then you can "stop" a car. This is not true in reverse! For example, you can drive a car on the highway, but can you drive any vehicle on the highway. The answer is no.

One of the key issues in Inheritance is when to "inherit" and when to use a data member variable. For example, should a 2-door sedan be a separate (child) class from a sedan, or should the number of doors be a member variable of sedan (or of car, or even of vehicle)! In this case, the number of doors is probably best left as a distinguishing detail of the sedan, not as a special sub-class in of its self.

When trying to decide when to subclass, you should think: "Would a new 'class' really define a specific 'sub-species' of the item, or would an extra member variable due to distinguish between two instances of the class.

        
          public class Two_Door_Sedan extends Sedan // Probably not a good idea
          ...

          public class Sedan extends Car //  Probably best to use a variable
          {
             var number_of_doors : int = 2;
             ...
          }
	
      

Polymorphism

Polymorphism is best summed up by the following:

  1. At compile time, a variable of the most general type is used to refer to an object that at run time may be any descendent type!

  2. At run time, "The object referenced by the variable behaves as it truly is, not as its variable is defined at compile time.

In an OOP, a variable of a "parent" type can refer to a variable of a child type, because, a car ISA vehicle, and a sedan ISA car. In fact, this ISA relationship is so important, that you will see ISA used as a keyword in the discussion on objects.

For example, if we have a car variable which is of type Car, can we say:

	
      var car   : Car   = new Sedan();
      var sedan : Sedan = new Sedan();  // both statements are LEGAL because a Car ISA Sedan
	
      

Yes! the car variable can contain a Sedan because a Sedan ISA Car!

BUT: For any code where the "car" variable is a CAR, the compiler will only allow the of "car functions" (even though what the variable references is really a Sedan). Further note: The sedan variable would have access to all Car properties and all Sedan properties as well!

So what exactly is polymorphism? Remember, a variable can normally only contain a value of the same type as the variable. With Polymorphism, a variable contain any value that is a subtype of the variable. Thus a Car variable can contain a Sedan, because a Sedan ISA Car.

Polymorphism is the ability for the computer to know at run time what is really inside the variable. For example, in the car variable above, when we call a function on the car, such as "car.drive()" if there is a Sedan.drive() function defined, then even though the car variable is TYPED only as a CAR, at run time, this instruction REALLY becomes a call to "Sedan.drive()"

Abstraction - Requiring Children to Implement Areas

Defining our "Abstract Base Class called Generic Shape

First, we can't really have a Generic Shape, we can't taste one, we can't display one, we can't see one... (All we can do is define the properties that many shapes have in common). Because this shape is just a generic representation of "all shapes" we use the term "Abstract". Here is how, in Java, we define our generic shape.

Remember, all code in java is placed in a "Class". Thus we use:

        public abstract class Generic_Shape
        {
        ...
        }
      

Putting all the "Common Data" into the "Abstract" Class

Ok, if we look back up at our definitions of what a shape is, we see that every shape has many things in common... these things are:

  1. Data
  2. Methods

In fact every Object in Java has Data and Methods.

The Data of interest is the center, the size, and the color.

What is "the center" of a two dimensional shape? Thats correct, the X value and the Y value. What is the "Type" of each? Correct, both are numbers. What type of numbers? Again, right, integers (the screen (your monitor) is made up of a whole bunch of individually numbered pixels).

Where do we store data with types? In variables (for more info click here). So lets define some variables:

  1. int x; // the center's x value
  2. int y; // the center's y value
  3. int size; // the "size" of the shape (means different things to different shapes)
  4. Color color; // the color to draw the object

So now our class file contains the following:

        public abstract class Generic_Shape
        {
          int x, y; // the center of the shape
          int size; // how big the shape is
          Color color; // the color to draw the object
        }
      

Fields or Object Variables

x, and y, and size, and color above are all called data fields of the object. We often also refer to them as the Object Variables.


An Objects' Constructor

The constructor of an object is a method that is called whenever you need a new object. The purpose of the constructor is to fill in all the fields (or variables) associated with an object. No object should ever be created without "Data".

Default Values: In other programming languages, such as C, the default value of a variable can be what ever happens to be in the memory of the computer at the time your program is run.... This can mean that a "salary" variable could hold -9101982309812 or a "name" variable could contain "lkjasdf10983o1jrln!@#!#@FWEJKLSDJF:LSJdf".

In Java, all variables default to a given value if you forget to assign them. The value is usually 0 (or NULL, which we'll talk about later). Even though there is a default value, always create a constructor for every object!

Here is our generic shape's default constructor:

	
       /**
        * Generic Constructor
        * 
        * @param x - center of shape x value
        * @param y - center of shape y value
        * @param size - size (can be overwritten or dismissed by children classes)
        */
        public function Generic_Shape ( starting_x :int,  starting_y :int,  starting_size : int)
        {
          this.x = starting_x;
          this.y = starting_y;
          this.size = starting_size;
        
          this.color = Color.red;
        }
	
      

Key Ideas behind the above constructor:

  1. "public"

    The public keyword tells Actionscript and Java (and other programmers) that this object can be created by anyone. Public means anyone. Alternatively in some cases, we will see the key word "Private". This means that only the object itself can use the function.

    Think of this as the door bell to your house and the dishwasher. Everyone can use the door bell (its public to the world). Only you are allowed to use your dishwasher (but perhaps other people could use the clean plates that the dishwasher produces...).

  2. Parameters: ( starting_x:int, starting_y:int, starting_size:int)

    These are symbolic names for the information that must be presented to the object when it is created. Without this information, the object will have no concrete representation. The information in these symbolic names, which is provided by the "caller" of the method, is almost always stored in to the object's variables.

  3. this

    Notice the use of the key word "this". This refers to the current object. "This" is a runtime (as well as compile time) concept. The use of this is not required, except where to avoid confusion between names.


Abstract Methods (Java only)

Remember, we are creating objects that we can draw or "paint" to the screen. Thus we must declare a method for doing this:

      
      /**
       * @param g - the graphics associated
       *            with the window (applet/frame) that contains this object
       */
      public abstract void paint (Graphics g);
      
    

Key ideas

  1. Comments: Every Method should be fully commented including a description of the parameters and the purpose of the method.

  2. abstract

    What does it mean to "paint" a "generic shape".... It has no meaning. But a "real shape" does need some way to draw it to the screen so everyone can see it.

    We know how to paint (draw) a square, we know how to paint (draw) a circle. Both of these are concrete (yet different) operations.

    Thus we put in this "dummy" method "declaration", the only purpose of which is to tell every shape that ISA generic shape that it must be able to paint itself (draw itself to the graphics screen).

    The keyword abstract is how we tell Java we want this behavior. Notice the ; at the end of the parameter list.

Common Functions

Every shape can move around the screen... thus we need another method that tells a shape how to move. Consider:

      
      /**
       * 
       * Move the center of the shape by the given amounts
       * 
       * @param deltaX - how far to move in the X dir
       * @param deltaY - how far to move in the Y dir
       */
      public void move (int deltaX, int deltaY)
      {
        x = x + deltaX;
        y = y + deltaY;
      }
      
    

Key Ideas

Moving a shape is something that all shapes have in common. Moving the center of a circle, or the center of a square, or the center of a ... is all based on "moving the center". Because the center is shared by all the objects, we can put the actual code for the method here in our Abstract Base Class. Here are some key ideas:

  1. comments - notice the "@param" this tells the programmer and Java that deltaX is a parameter to the method.

    In fact, Java has a builtin way of creating web pages describing how to use an object (in fact, see Sun's own JAVA docs). The key word "@param" tells Java some information toward building these fancy documentation web pages.

  2. public - who ever creates our shape, can also move it, thus, we make this method public (accessible by all).

  3. void

    unlike mathematical functions, this function doesn't "compute" anything. The key word "void" tells Java (and the programmer) that this function does not "return" a value.

  4. x = x + deltaX;

    This is a small mathematical operation that tells the Object to update the value of the X coordinate of the center to a new value (calculated by adding the old value to the parameter deltaX).


Child Classes (Sub-Classes)

Creating an actual (non-abstract) class that uses Generic_Shape

Ok, we've worked hard to put (most of) our functionality into the Generic_Shape class, because we don't want to have to repeat the work for all of our "sub"-classes (or children Classes.

Lets now create a square class that ISA generic_shape... Again, remember that ISA means, the square class acts in many ways like a generic shape, but in a few ways uniquely like a square.

Additional example

A Student ISA Person. A professor (contrary to popular belief) ISA Person. Professors and Students have many of the same properties, and many different ones. By using Object Oriented programming, we can share all the stuff (variables and methods) that is common, and only differentiate when important differences are created.

Key Ideas

  1. public - again, everyone can create/use squares.

  2. class - square is a class (at run time, an object)

  3. extends - ISA Generic_Shape.

    extends means that the Square class inherits all the abilities of the Generic_Shape class.

  4. Generic_Shape - the parent or base class.


Back to Topics List