What is OOP (Object Oriented Programming)?

I received this letter recently asking me about OOP (Object Oriented Programming):

“I was hoping you could clarify something for me. Are all web development projects object-oriented, or is object-oriented a programming technique? Can an object-oriented web development project be called a "custom development" project? Aren’t the objects, in a very basic way, "chunks" of code already written for reuse for certain, commonly used functions in any application needing that function?


Any help would be appreciated. I am resurrecting my technology project management career, and just want to make sure I’m representing my old work correctly…

Thanks!

Amata”

Excellent questions Amata!  The concept of OOP is confusing to most people, until they learn it.  I’m going to explain what it is, but first, I want to tackle each of your questions, one at a time:

  • Are all web development projects object-oriented?
    • Most definitely not.  Many are and many are not.  It depends on what technology and language the developer(s) who created the web application chose.  For example:
      • Classic ASP (Active Server Pages) was Microsoft’s technology before they released the newer technology called “.NET” (pronounced “Dot Net”).  Classic ASP is not object oriented.  Though, it does allow for the use of COM components, which themselves are partially object oriented.  Classic ASP consisted of creating HTML pages, then embedding VB Script in them.  The VB script ran on the server and was NOT object oriented, but if you had COM components installed on the web server, this VB script could ask the server to create an instance of an object and then call methods on it.  But, you could not create classes in VB script.  You could not inherit from any classes.  Those are very important concepts in OOP.  VB Script is an interpreted language, so it’s not as fast as byte-code compiled technologies like Java & .NET.  Fewer and fewer people are creating new web apps with classic ASP (VBScript) because its descendant (.NET) has been out since February 2002.  There’s really no excuse to create a new project in classic ASP these days.
      • PHP:  This is a very popular language for web development and has been around for a long time (since the mid 90’s or so).  The latest versions of this language do support object oriented programming, but older versions did not.  So, there are many web sites out there written in PHP that are not object oriented, and many that are object oriented.  PHP is similar to VB script in that you create HTML pages and embed PHP code inside of them.  The PHP is run on the server, while the HTML is delivered to the client browser.
      • Python:  This is another server side scripting language.  Python is an object oriented language, so any program (web site or other) you create with Python is object oriented.  This is an interpreted language too.
      • Java:  Java is now and has been since it’s creation, a fully object oriented language.  Anything written in Java is object oriented.  A web application written in Java is object oriented.  The Java code runs on the server side.  Though Java “applets” can be made to run on the client side, in the browser.  Java is not to be confused with “Java Script”, which shares only a name likeness to the Java language.  JavaScript is a language that runs on the client’s browser and is interpreted, not compiled.  Though, the latest and greatest versions of FireFox and Chrome are now compiling JavaScript on the client, just before they run it, so that it runs significantly faster.  Java is a byte-compiled language that runs in a virtual machine.
      • .NET:  is Microsoft’s alternative to Java (though, ask any Microsoft ambassador and they’ll deny this).  .NET was designed to be fully object oriented (and it is).  It replaces classic ASP and old VB6.  It’s two primary languages are C# and VB.NET, though there are dozens of other .NET languages available, including .NET versions of languages that existed before .NET like Delphi (Object Pascal), C++, PHP, RPG, Cobol, and many others.  Other languages that are somewhat newer and are not .NET languages, also have .NET versions like Python and Ruby.  .NET web applications have HTML in one file and the .NET language code in another file (so they don’t mix).  You get a full IDE with color syntax highlighting, intellisense, integrated help, debugging, etc…  You also get a visual designer for the HTML page and you can drag and drop visual components onto the page like text boxes, labels, buttons, radio buttons, data grids, and you can create your own custom components.  These components are “objects” in the truest sense of the OOP concept.  This means you can write code against them in your code behind source code.  It is a remarkable advancement in web development.  As you can tell from the title of my blog, I highly recommend this as the best option for web development (also for Windows development, Windows Mobile development (and now iPhone development), Games development, XBox 360 development, Linux development, Mac OSX development (Linux and Mac would be using the Mono framework instead of the .NET framework).
      • Many, many others… too many to list here.
  • or is object-oriented a programming technique?
    • It’s more of a concept than a technique.  You can emulate OOP coding styles in non-OOP languages, but you can’t fully implement OOP unless the language you’re using was designed to be an OOP language.  You can however, use an OOP language and not write OOP code.  No one in their right mind does this though.  It would be like buying the highest end HD, 3D camcorder and using it for nothing more than the on-screen clock.
  • Can an object-oriented web development project be called a "custom development" project?
    • Absolutley!  Any web development project that’s not just a purchase of existing software and installed on a server, by definition, is a custom developed project.  If you create a web site by coding the HTML and writing the code that processes the input, you’ve created a custom development project.  Whether it’s OOP or not plays no role in whether or not it’s custom.
  • Aren’t the objects, in a very basic way, "chunks" of code already written for reuse for certain, commonly used functions in any application needing that function?
    • Kind of.  Although, there are pre-written objects that you can use (and in virtually all applications you write, you will be using plenty of pre-written objects), you’ll also be creating your own, custom objects as well.  For example, in .NET, your program itself is an object.  You can’t avoid creating your own objects in .NET.  Also, the objects you create don’t necessarily have to be reusable (though, 99.99% of the time they are), but if you create a new object type, there’s nothing that says you have to use it more than once.  But yes, the general idea of OOP is that it improves your ability to reuse code.  BTW, just because something is reusable, does not make it OOP.  Further below, where I describe OOP, this will become more clear.  Also, a collection of pre-written functions is not necessarily an object.  Though object generally do have functions (or “methods”) in them, that’s not what makes them objects.  Very generally, objects are data structures that also have code.
  • (I added this question myself because I get it a lot):  What can I do in OOP that I can’t do in plain old procedural programming?
    • Nothing.  That’s not the point of OOP.  OOP isn’t designed to let you create apps that couldn’t be created using older technology.  Heck, if you want to code the next great app in Assembly Language with an Assembler and punch cards, there’s nothing stopping you (except for time, frustration, delays due to bugs and typos, and losing your job for wasting time).  OOP is designed to let you create the same applications with the same functionality, only sooner, with fewer bugs, that’s easier to make changes to.  Essentially, given the same budget and time, with OOP, you’ll get more done and with fewer problems.  I should point out that even though there’s nothing functionality wise in a custom application that OOP gives you that non-OOP doesn’t, there are significant things you can do in code in an OOP program that you simply cannot do without an OOP language.
  • (I added this question as well, for the same reason as above):  Should I only use OOP for very large programs, but procedural for everything else?
    • You should use OOP for everything.  Period.  OOP is not a burden.  Procedural programing is a burden (in comparison).  Besides, of all the programs I’ve written with the expectation that they’ll be “small”, few, if any, ever remain small.  Anyway, it doesn’t matter.  Why not start it out right from the beginning?  OOP does NOT take more effort, so why avoid it?

If you’d like to ask me a question too, please do so by leaving a comment.  Don’t worry:  Your comments are not published until I approve them.  If you wish to remain anonymous, just say so and I won’t publish your name.

OOP Explained:

In a nut shell, OOP means you have a “chunk of code” (as Amata called it) that is also packaged together with a data structure.  The “chunk of code” is actually a collection of subroutines (called “Methods” in OOP).  You may design a class that represents an employee, for example.  That class may have data fields for first name, last name, employee number, and anything else you might find useful to be properties of an employee.  Then, like in non OOP languages, you can declare a variable (a.k.a. and “object”) of your employee type.  Here’s an example of a non OOP way of doing this:


  1: struct EmployeeStruct
  2: {
  3:     string   FirstName;
  4:     string   LastName;
  5:     int      EmployeeNumber;
  6:     string   SSN;
  7:     string   HireDate;
  8:     decimal  salary;
  9: }
 10: 
 11: void main()
 12: {
 13:     EmployeeStruct employee1;
 14:     EmployeeStruct employee2;
 15:     
 16:     employee1.FirstName = "John";
 17:     employee1.LastName = "Smith";
 18:     employee1.EmployeeNumber = 123456;
 19:     employee1.SSN = "123-45-6789";
 20:     employee1.HireDate = "1998-06-15";
 21:     employee1.salary = 75000;
 22: 
 23:     employee2.FirstName = "Jane";
 24:     employee2.LastName = "Doe";
 25:     employee2.EmployeeNumber = 654753
 26:     employee2.SSN = "923-45-6789";
 27:     employee2.HireDate = "1997-02-09";
 28:     employee2.salary = 76000;
 29: }

The code above defines a data structure that defines the data fields that represent an employee.  The main routine declares 2 variables of type “EmployeeStruct”.  It then proceeds to set data values on both employee struct instances.  This is not OOP code, even though I used an OOP language to code it.

Let’s add some functionality in a non-OOP way, then we’ll convert the code into a fully object oriented program.  The changes in syntax between the two will be subtle, but the capabilities between the two are drastic.


  1: struct EmployeeStruct
  2: {
  3:     string   FirstName;
  4:     string   LastName;
  5:     int      EmployeeNumber;
  6:     string   SSN;
  7:     string   HireDate;
  8:     decimal  salary;
  9: }
 10: 
 11: void main()
 12: {
 13:     EmployeeStruct john;
 14:     EmployeeStruct jane;
 15:     
 16:     john.FirstName = "John";
 17:     john.LastName = "Smith";
 18:     john.EmployeeNumber = 123456;
 19:     john.SSN = "123-45-6789";
 20:     john.HireDate = "1998-06-15";
 21:     john.salary = 75000;
 22: 
 23:     jane.FirstName = "Jane";
 24:     jane.LastName = "Doe";
 25:     jane.EmployeeNumber = 654753
 26:     jane.SSN = "923-45-6789";
 27:     jane.HireDate = "1997-02-09";
 28:     jane.salary = 76000;
 29: 
 30:     decimal JohnsWeeklySalary = GetWeeklySalary(&john;);
 31:     RaiseSalaryByPercent(jane, 10);
 32: }
 33: 
 34: decimal GetWeeklySalary(EmployeeStruct* employee)
 35: {
 36:     return employee->salary / 52;
 37: }
 38: 
 39: void RaiseSalaryByPercent(EmployeeStruct employee*, int PercentToRaise)
 40: {
 41:     employee->salary = employee.salary * (1 + PercentToRaise/100);
 42: }

Here, we’ve added two subroutines that take a pointer to an EmployeeStruct and either do a calculation to return a new value (as in GetWeeklySalary) or make changes to the employee data itself (as in RaiseSalaryByPercent).  The language I’m using isn’t a real language, but it’s very similar to C.  I just made it up… It’s pseudo-code.

Now, let’s rewrite this in a C# like language, but more specifically, in a fully OOP manor:


  1: public class EmployeeType
  2: {
  3:     public string   FirstName;
  4:     public string   LastName;
  5:     public int      EmployeeNumber;
  6:     public string   SSN;
  7:     public string   HireDate;
  8:     public decimal  salary;
  9: 
 10:     public decimal WeeklySalary
 11:     {
 12:         get{return this.salary / 52;}
 13:         set{this.salary = value * 52;}
 14:     }
 15: 
 16:     public void RaiseSalaryByPercent(int PercentToRaise)
 17:     {
 18:         this.salary = this.salary * (1 + PercentToRaise/100);
 19:     }
 20: 
 21: }
 22: 
 23: void main()
 24: {
 25:     var john = new EmployeeType();
 26:     var jane = new EmployeeType();
 27:     
 28:     john.FirstName = "John";
 29:     john.LastName = "Smith";
 30:     john.EmployeeNumber = 123456;
 31:     john.SSN = "123-45-6789";
 32:     john.HireDate = "1998-06-15";
 33:     john.salary = 75000;
 34: 
 35:     jane.FirstName = "Jane";
 36:     jane.LastName = "Doe";
 37:     jane.EmployeeNumber = 654753
 38:     jane.SSN = "923-45-6789";
 39:     jane.HireDate = "1997-02-09";
 40:     jane.salary = 76000;
 41: 
 42:     decimal JohnsWeeklySalary = john.WeeklySalary;
 43:     jane.RaiseSalaryByPercent(10);
 44: }
 45: 
 46: 

This code is now object oriented.  Notice that the struct is now called a class.  The two new subroutines were moved INTO the class and the EmployeeStruct* parameters were removed from the arguments list.  The GetWeeklySalary subroutine was redone to become a property instead of a method.  Inside the “main” routine, the 1st 2 lines now instantiate a new EmpoyeeType object by calling its default constructor.  The rest of the main method is identical to before, except for the last two lines.  As you can see, getting the WeeklySalary on john is a simple matter of accessing the WeeklySalary property on the john object (the john object is an instance of the EmployeeType class.  The jane object is another instance of the same class type.  john and jane are both objects).

There’s nothing particularly special revealed here, except maybe the WeeklySalary property.  A property on a class is essentially two subroutines called “getters” and “setters”.  The property looks and smells like a data field, but you can do calculations inside of them (or anything, really).  Notice that you can set the salary field by “setting” the WeeklySalary property.  The math is done inside of the setter and the correct value is applied to the salary field.

Like I said; nothing particularly special.  But now we have the ability to create new classes based off the old classes.  In other words, we can extend the existing classes by inheriting from an existing class.  Let’s go ahead and do that with the EmployeeType class.  Let’s mimic the real world where most companies have many different types of employees.  For this simple example we’ll have salaried and hourly employees.  We’ll create a base class of employee, then we’ll create 2 new classes that inherit from the base employee class.  One will be salaried and the other will be hourly.


  1: public virtual class EmployeeType
  2: {
  3:     public string  FirstName;
  4:     public string  LastName;
  5:     public int     EmployeeNumber;
  6:     public string  SSN;
  7:     public string  HireDate;
  8:     public virtual decimal WeeklyPay;
  9: 
 10:     public virtual void RaisePayByPercent(int PercentToRaise);
 11: }
 12: 
 13: public class HourlyEmployeeType: EmployeeType
 14: {
 15:     public int     MinimumHoursPerWeek;
 16:     public decimal wage;
 17: 
 18:     public override decimal WeeklyPay
 19:     {
 20:         get{return this.wage * this.MinimumHoursPerWeek;}
 21:         set{this.wage = value / thsi.MinimumHoursPerWeek;}
 22:     }
 23: 
 24:     public virtual void RaisePayByPercent(int PercentToRaise)
 25:     {
 26:         this.wage = this.wage * (1 + PercentToRaise/10);
 27:     }
 28: }
 29: 
 30: public class SalariedEmployeetype: EmployeeType
 31: {
 32:     public decimal salary;
 33: 
 34:     public override decimal WeeklyPay
 35:     {
 36:         get{return this.salary / 52;}
 37:         set{this.salary = value * 52;}
 38:     }
 39: 
 40:     public override void RaisePayByPercent(int PercentToRaise)
 41:     {
 42:         this.salary = this.salary * (1 + PercentToRaise/100);
 43:     }
 44: }
 45: 
 46: void main()
 47: {
 48:     var john = new HourlyEmployeeType();
 49:     var jane = new SalariedEmployeetype();
 50:     
 51:     john.FirstName = "John";
 52:     john.LastName = "Smith";
 53:     john.EmployeeNumber = 123456;
 54:     john.SSN = "123-45-6789";
 55:     john.HireDate = "1998-06-15";
 56:     john.wage = 7.45;
 57: 
 58:     jane.FirstName = "Jane";
 59:     jane.LastName = "Doe";
 60:     jane.EmployeeNumber = 654753
 61:     jane.SSN = "923-45-6789";
 62:     jane.HireDate = "1997-02-09";
 63:     jane.salary = 76000;
 64: 
 65:     decimal JohnsWeeklyPay = john.WeeklyPay;
 66:     decimal JanesWeeklyPay = jane.WeeklyPay;
 67:     jane.RaisePayByPercent(10);
 68:     john.RaisePayByPercent(5);
 69: 
 70:     CutPayByPercent(jane, 5);
 71:     CutPayByPercent(john, 1);
 72: }
 73: 
 74: void CutPayByPercent(EmployeeType employee, int PercentToCut)
 75: {
 76:     employee.RaisePayByPercent(PercentToCut * -1);
 77: }
 78: 

We now have three classes:

  1. The base employee class called “EmployeeType”.
  2. The hourly employee class called “HourlyEmployeeType”;
  3. The salaried employee class called “SalariedEmployeeType”;

Note that the EmployeeType is now virtual, meaning that you cannot instantiate an instance of this type.  To use it, you have to create a new class that inherits from it.  The new class inherits all of the base classes fields, properties, and methods.  Then, you add more that are specific to that inherited class.  For example, the object john is of type HourlyEmployeeType, and the first & last names were not added to that class, yet HourlyEmployeeType already has them because it inherited them from the base type.  The same is true for the SalariedEmployeeType.  These inherited (or “extended”) types add what’s unique to their new type.  You can still call methods of on jane and john that were imlemented in the base type.  This is because jane is not just a SalariedEmployeeType, she’s also an EmployeeType at the same time!  john is an HourlyEmployeeType and an EmployeeType at the same time!  So, john and jane are different types and they’re the same types at the same time.

Note also that I added a new routine near the bottom called “CutPayByPercent” that takes neither an HourlyEmployeeType nor a SalariedEmployeeType, yet I was able to pass both of them to the CutPayByPercent method.  The reason this worked is because both jane and john inherit from the EmployeeType class and the CutPayByPercent method takes any object of type EmployeeType.

This is an example of another object oriented concept called “polymorphism”Polymorphism is the ability for an object to be treated as different types of objects (depending on its inheritance tree).

I’m not going to give a full blown tutorial on OOP here, but this should get your toes wet.

The primary concepts in object oriented programming are:

  • Abstraction
  • Containment
  • Inheritance
  • Polymorphism

Any language that directly supports these concepts is an object oriented language.  Some languages (like Visual BASIC 6 and earlier (before .NET)) only implements some of these concepts, making them only partially object oriented.  C# and VB.NET are fully object oriented, as well as MANY other languages.

OOP was created to help you think about the tasks like a normal person would think of it, not like a computer would.  You create objects in code representing real world objects.  You add properties to them an functionality (by adding methods).  Then you instantiate individual objects and ask them to do stuff to themselves (like asking them to raise their salary, for example).  This package of code + data is what makes an object.  Letting new object types inherit from old ones gives up inheritance.  Being able to treat objects as if they’re their own base types is called polymorphism.

All of this combined lets you abstract the low level details.  Putting multiple data items (like first name, last name, etc…) is called containment.  You’re not limited to basic types in your data fields.  ANY type that’s available can be used as a data field.  For example, you could have another class, who has a data field of type HourlyEmployeeType.  There’s no limit.

Please, ask questions in the comments section below this article if you’d like to see any of this elaborated upon.

Leave a Reply