Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Note: this question is an edited excerpt from a blog posting I wrote a few months ago. After placing a link to the blog in a comment on Programmers.SE someone requested that I post a question here so that they could answer it. This posting is my most popular, as people seem to type "I don't get object-oriented programming" into Google a lot. Feel free to answer here, or in a comment at Wordpress.

What is object-oriented programming? No one has given me a satisfactory answer. I feel like you will not get a good definition from someone who goes around saying “object” and “object-oriented” with his nose in the air. Nor will you get a good definition from someone who has done nothing but object-oriented programming. No one who understands both procedural and object-oriented programming has ever given me a consistent idea of what an object-oriented program actually does.

Can someone please give me their ideas of the advantages of object-oriented programming?

share

locked by World Engineer Sep 5 '13 at 14:02

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

closed as too broad by gnat, Yusubov, GlenH7, World Engineer Sep 5 '13 at 14:02

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

2  
Ooh, nice one -- it's tricky to come up with a definition that everyone who says they do OOP will agree with! (Even neglecting those who are really just doing e.g. procedural programming in OOP clothing.) –  SamB Sep 24 '10 at 17:21
10  
It really sounds like "I don't get C programming. Can't we just use assembly language?" to me. –  tia Sep 24 '10 at 17:56
2  
@Joel: I don't necessarily know the same uninformed proponents as you do, but I think a good part of it may well be that they were introduced to programming by classes in OO languages. If that's your baseline, you don't understand how it's a step up. My first language was Applesoft BASIC, and I'd learned a handful of BASIC dialects, plus C, Pascal and a bit of x86 assembly before I was introduced to OOP by Delphi and C++. People who have experienced the difference are better able to explain it. –  Mason Wheeler Sep 24 '10 at 20:04
3  
More negative comments about OOP here: harmful.cat-v.org/software/OO_programming , including quotes from Dijkstra and Rob Pike. –  imgx64 Sep 25 '10 at 17:38
3  
@Joel: You hit my objection to OOP on the head. The people who are OOP one-true-wayists typically have a straw-man view of procedural programming and have little to no experience in any other paradigm at all. Functional programming would look utterly alien to them (evidence: count the number of people recently asking how to do classes and objects in Erlang for some bizarre reason) and logic programming would explode their heads I'm convinced. I can only imagine what some of the actually strange paradigms would do to them.... –  JUST MY correct OPINION Feb 10 '11 at 2:58

11 Answers 11

up vote 7 down vote accepted

Think of software as a machine or assembly line that exists inside the computer. Some raw materials and components are fed into the machine, and it follows a set of procedures to process them into some final product. The procedures are set up to perform a specific operation on some raw material or component to a specific set of parameters (eg, time, temperature, distance, etc) in a particular order. If the details of the operation to be performed were incorrect, or the machine's sensors aren't correctly calibrated, or if some raw material or component wasn't within expected quality standards, it could change the operation's outcome and the product would not turn out as expected.

Such a machine is very rigid in its operation and acceptable inputs. Machines don't question the designers' intelligence nor its current operating environment. It will continue to follow procedures as long as it's directed to. Even if a change in raw materials or components could have a dramatic effect on what happened in later operations, the machine would still perform its procedures. The process would need to be reviewed to see what changes to the procedures were necessary to compensate and produce the desired result. A change to the product's design or configuration might also require a significant change to the operations performed or their order. Although those in charge of production quickly learned the importance of isolating operations as much as possible to reduce undesirable effects between them, a lot of assumptions are made of the condition components are in as they undergo processing; assumptions that might not be detected until the final product is in the hands of the user in some different operating environment.

That's what procedural programming is like.

What object-orientation provides is a way to remove the assumptions of the condition of components; thus, the operations to be performed on that component and how to integrate it into the final product. In other words, OOP is like taking the process details for dealing with some particular component and giving it to a smaller machine to do. The larger machine responsible for the process tells the component-specific machine which operation it expects to be done but leaves the details for the steps to the component-specific machine to handle.

As to the advantages of object-orientation over non-object-oriented software:

  • component-specific behavior - making details on how to handle a particular component the responsibility of the smaller component-specific machine ensures any time that component is handled, its machine will do so appropriately;
  • polymorphic expressions - because component-specific machines performs operations tailored to its particular component, the same message sent to different machines can act differently;
  • type abstraction - it often makes sense for several different types of components to use the same vocabulary for the operations their machines do;
  • separation of concerns - leaving component-specific details to their machines means the process machine only needs to handle the more general, larger concerns of its process and the data required to manage it; plus, it's less likely to be affected by changes in other components;
  • adaptability - components that focus on their area of speciality can be adapted to unforeseen use simply by changing the components it uses, or making it available to another process machine;
  • code reuse - components with a narrow focus and greater adaptability can leverage their development cost by being put to use more often.
share
3  
Everything you said seems to apply equally to functional programming, highlighting the problem here. –  Jesse Millikan Feb 9 '11 at 22:16
1  
Except the OP didn't ask about functional programming, so your comment lacks merit. Particularly so since my answer is the one accepted. –  Huperniketes Feb 24 '11 at 4:59
    
Functional programming is naturally close to Object Oriented, in fact one could argue that functional programming is in fact a more "pure" form of object orientation where functions themselves become first class objects. Still a noob in all that functional programming thing though, still, it is how it feels like for me at the moment. –  Newtopian Nov 16 '11 at 4:55

I think the Wikipedia page is a good place to get the fundamentals:
http://en.wikipedia.org/wiki/Object-oriented_programming

Basically the idea is that procedural programming, which is what OOP was trying to improve upon, focused on the processes being modeled. OOP shifts to a model where the focus is on the "things" you are modeling, and the processes and data of those things are contained within those things.

So, as an example, let's say you were designing an application to track a task list. In procedural programming, your top level entities in the model would be the processes that occur, such as creating a task, removing a task, changing the task info, etc. In an OOP model, you would instead focus on creating a Task, and think about what data and processes that Task should be responsible for. And then focus on what other objects Task should interact with, such as possibly a Note or something if you want to keep notes about Tasks.

I hope that helps. Just keep on reading about it and looking at code and it will suddenly "click". That was my experience.

share
    
Downvoter care to give a reason? –  RationalGeek Feb 15 '11 at 20:38
    
It seems that you probably haven't even read the entire question asked, much less poked into the linked blog entry. The author doesn't have a problem with the fundamentals, as far as I can tell. So, basically, -1 for answering a question you wanted to answer rather than the question being asked. –  Jesse Millikan Jun 14 '11 at 18:42

From your blog, it seems that you're familiar with both imperative and functional programming, and that you're familiar with the basic concepts involved in object-oriented programming, but you've just never really had it "click" as to what makes it useful. I'll try to explain in terms of that knowledge, and hope that it's helpful to you.

At its core, OOP is a way to use the imperative paradigm to better manage high degrees of complexity by creating "smart" data structures that model the problem domain. In a (standard procedural non-object-oriented) program, you've got two basic things: variables, and code that knows what to do with them. The code takes input from the user and various other sources, stores it in variables, operates on it, and produces output data which goes to the user or various other locations.

Object-oriented programming is a way to simplify your program by taking that basic pattern and repeating it on a smaller scale. Just like a program is a large collection of data with code that knows what to do with it, each object is a small piece of data bound to code that knows what to do with it.

By breaking down the problem domain into smaller pieces and making sure as much data as possible is bound directly to code that knows what to do with it, you make it a lot easier to reason about the process as a whole and also about the sub-issues that make up the process.

By grouping data into object classes, you can centralize code related to that data, making relevant code easier both to find and to debug. And by encapsulating the data behind access specifiers and only accessing it through methods, (or properties, if your language supports them,) you greatly reduce the potential for data corruption or the violation of invariants.

And by using inheritance and polymorphism, you can reuse preexisting classes, customizing them to fit your specific needs, without having to either modify the originals or rewrite everything from the ground up. (Which is a thing you should never do, if you can avoid it.) Just be careful you understand your base object, or you could end up with killer kangaroos.

To me, these are the fundamental principles of object-oriented programming: complexity management, code centralization and improved problem-domain modeling through the creation of object classes, inheritance and polymorphism, and increased safety without sacrificing power or control through the use of encapsulation and properties. I hope this helps you understand why so many programmers find it useful.

EDIT: In response to Joel's question in the comments,

Can you explain what an "object-oriented program" contains (other than these fancy defintions you've outlined) that is fundamentally different from an imperative program? How do you "get the ball rolling?"

A little disclaimer here. My model of "an object-oriented program" is basically the Delphi model, which is very similar to the C#/.NET model since they were created by former Delphi team members. What I'm saying here may not apply, or not apply as much, in other OO languages.

An object-oriented program is one in which all the logic is structured around objects. Of course this has to be bootstrapped somewhere. Your typical Delphi program contains initialization code that creates a singleton object called Application. At the start of the program, it calls Application.Initialize, then a call to Application.CreateForm for every form you want to load into memory from the beginning, and then Application.Run, which displays the main form on screen and starts up the input/event loop that forms the core of any interactive computer programs.

Application and your forms poll for incoming events from the OS and translate them into method calls on your object. One thing that's very common is the use of event handlers, or "delegates" in .NET-speak. An object has a method that says, "do X and Y, but also check to see if this particular event handler is assigned, and call it if it is." An event handler is a method pointer--a very simple closure that contains a reference to the method and a reference to the object instance--that's used to extend the behavior of objects. For example, if I have a button object on my form, I customize its behavior by attaching an OnClick event handler, which causes some other object to execute a method when the button is clicked.

So in an object-oriented program, most of the work gets done by defining objects with certain responsibilities and linking them together, either through method pointers or by one object directly calling a method defined in another object's public interface. (And now we're back to encapsulation.) This is an idea that I had no concept of back before I took OOP classes in college.

share
4  
I think you really hit the nail on the head with this answer. When you encapsulate data manipulation (OK, they are allocating a pointer here and then shifting a few bits there...) all that is left is the high level logic of the program (If done properly, you can write horrible code in any paradigm.). –  ChaosPandion Sep 24 '10 at 17:35
2  
That's a great explanation, thank you. Can you explain what an "object-oriented program" contains (other than these fancy defintions you've outlined) that is fundamentally different from an imperative program? How do you "get the ball rolling?" –  Joel J. Adamson Sep 24 '10 at 19:54
1  
+1: I think you really got it with "it's basically trying to repeat the same things on a smaller scale", basically another level of abstraction (or well, more like another possible level to create abstraction). –  n1ckp Oct 11 '10 at 15:31
1  
@Karthik A bit late to the party, but actually no, OOP need not mean just reusing classes. The whole concept of a type system is an abstraction for grouping objects together under common interfaces. But you can also use a prototype-based system (like Javascript) where method calls on the object resolve up the prototype chain instead of up the class chain. It still has all the features of OOP, but allows for ad-hoc objects and types by simply adding new stuff onto an existing object. Then you can clone that object to get more of that new type. –  CodexArcanum Nov 1 '10 at 21:01
2  
+1 for exatly pointing the true advantage of OOP. "At its core, OOP is a way to use the imperative paradigm to better manage high degrees of complexity by creating "smart" data structures that model the problem domain. " –  Karthik Sreenivasan Feb 1 '12 at 4:06

OOP attempts to model real world concepts in terms of objects and interactions between them. As humans, we tend to process the world in terms of objects. The world is full of objects that have certain properties and can do stuff like interact with other objects. OOP allows to model the world in similar terms. For example,

  • Person is an Object. A person has some properties, like age and gender. A person can do things: eat, sleep, drive a car.
  • Car is also an Object (although of different type). It also has properties like make, model and year. A car can do things: move.

But a car can't move on its own, it needs a person to drive it - interaction between Objects.

share
    
I get it: that makes sense. However, I think one of the really cool things about programming a computer is that we don't have to think in terms of how "real world" objects do things. I think more mathematically (I'm a mathematician doing biology research). This was an "a-ha" (a meditative insight), not an attitude going in. However it has greatly affected how I do my work. –  Joel J. Adamson Sep 24 '10 at 19:58

The way I first understood it is :

Before Object-oriented programming, you had Structured programming. Everything is centered around the process. The first question you got to ask yourself is "What I want to do with the information?".

With Object-oriented programming, it's centered around the data. The first question you got to ask yourself is "Witch information I need to deals with?". This make abstraction easier.

share

I wrote a blog post a while ago that you might find helpful: Procedural vs. OOP Explained.

share
    
I dont know why people voted it down! This article is better then all of of theese above together! my vote for +1 –  Haris Sep 14 '12 at 13:30
    
Its voted down because its just a link-and-run, which is highly discouraged. See the meta stackoverflow question: Are answers that just contain links elsewhere really “good answers”? –  icc97 May 23 '13 at 9:38

There's various sorts of OO systems, and it's hard to get a definition everybody will agree on. Rather than try to show how Java's OO is similar to the Common Lisp Object System, I'll start with something more conventional, step by step.

Suppose you have a lot of objects existing as scattered data. Points, for example, might be elements in an X, a Y, and a Z array. In order to consider a point itself, it makes sense to pull all the data together into something like a C struct.

Now, for any data object, we've got the data all together. However, in a procedural program, the code is scattered. Suppose we're dealing with geometric shapes. There's a large function to draw shapes, and it needs to know about all the shapes. There's a large function to find area, and another for perimeter. The code for a circle is scattered through multiple functions, and in order to add another type of shape we need to know which functions to change. In an object-oriented system, we gather the functions into the same kind of thing (class) as the data. Therefore, if we want to look at all the circle code, it's there in the Circle definition, and if we want to add a Quartercircle we simply write its class and we've got the code.

One side benefit from this is that we can maintain class invariants, things that are true about each member of the class. By restricting code outside the class from directly messing with class data members, we've got all the code that can change class data in one place, and we can confirm that it doesn't do anything screwy (like have a triangle with one leg longer than the other two combined). This means we can count on some properties of every member of the class, and don't have to check to see if an object is sane every time we use it.

The main benefit comes with inheritance and polymorphism. By defining all of these various shapes as subclasses of a class called Shape, we can have our code manipulate Shapes, and it's the job of the shape subobjects to do whatever is called for by the manipulations. This means we needn't touch the old tested code when we add new shapes or refine the behavior of older ones. We automatically have old code that can directly take advantage of new code. Instead of making the controlling code aware of all the different possible shapes, and having to maintain functions that are aware of all the different possible shapes, we merely deal with shapes and their properties, while maintaining Shape subclasses. This simplifies the controlling code.

We have several advantages here. Since we have class invariants, we can reason about larger data objects in the same way we reason about built-in types, meaning we can often split up complex concepts into simpler ones. Since the circle code is largely contained in Circle, we have increased locality. Since there aren't concepts of a circle scattered through several different functions in different places, we get less coupling between routines, and don't have to worry about keeping them in sync. Since classes are, in effect, types, we can take advantage of the existing type system to catch incompatible use of our classes.

share

I think OOP is basically just a name given to something you may have been tempted to do along the way, as I was.

Way back when I was a baby programmer, even in Fortran, there was such a thing as a pointer to a subroutine. It is really useful to be able to pass a pointer to a subroutine as an argument to another subroutine.

Then the next thing that would be really useful would be to store a pointer to a subroutine inside a record of a data structure. That way, you might say the record "knows" how to do operations on itself.

I'm not sure if they ever built that into Fortran, but it's easy to do in C and its descendents.

So underneath, it's a simple and useful idea that you might have been tempted to do yourself, and is easier to do in more recent languages, even if some people turned it into a giant bandwagon full of scary buzzwords.

share

OOP = data structures + message passing + inheritance, all of which are logical evolutions in programming models.

OOP can be understood (by programmers) in about 90 seconds (see my profile for a link). The concepts are very simple.

How to apply it is another matter. Just because you know how to swing a hammer doesn't mean you know how to design and build a house. ;-)

share
    
+1 - I agree. How to apply OOP took quiet a lot of practice and time although just knowing what they are did not take much time at all as the implication is the key word here. –  Karthik Sreenivasan Feb 1 '12 at 4:21

OO has many different definitions, yes. I'm sure you can find lots of these on your own. I personally like Rees Re: OO as a way to make sense of them. I'm guessing you've read that already since you quote Paul Graham. (I recommend it to anyone interested in OO.) I'm going to more or less adopt the Java definition here {1,2,3,7,8,9}.

The question of the utility of OO, especially the way I approach it, deserves a much larger answer with a few thousand lines of code (partly in order not to just be a bunch of assertions). However, here's a summary of that hypothetical document.

I don't think OO is terribly useful at a small scale, say, about a few hundred lines. In particular, OO languages without good functional influences tend to make it really painful to get simple things done with any kind of collection or anything that needs many data types. This is where most design patterns come into play; they're band-aids on the low power of the underlying language.

At about a thousand lines, it starts to be harder to keep track of all the operations and data structures and how they relate. It helps, at this point, to have a way to explicitly organize data structures and operations, to draw module boundaries and define responsibilities, and to have a convenient way to understand those definitions while you're trying to program against them.

Java-ish OO is a halfway solution to these problems that happens to have won the popularity contest. Because it's the same mechanism that Java people apply to the small scale problems created by an underpowered language, it tends to start looking more like a magic solution to everything than just a way to stay organized. People familiar with functional programming tend to prefer other solutions, like CLOS or Haskell's type classes, or template metaprogramming when stuck in C++, or else (like me, working daily in C#) use OO but just don't get all that excited about it.

share
    
+1 - Great answer. "I don't think OO is terribly useful at a small scale." –  Karthik Sreenivasan Feb 1 '12 at 4:15
    
I even read an article (dl.acm.org/citation.cfm?id=326103) stating that OOP does not show any real productivity advantage wrt to procedural for the first two releases of a software product. As far as I understand, only starting from the third release you have real advantages because you can better reuse / refactor code written in an OO style than in a procedural style. –  Giorgio Sep 8 '12 at 18:51

Since you understand structs, and you understand function pointers, and you understand structs with function pointers, from your perspective I would define object oriented programming as simply "programming, with heavy use of structs that have function pointers". It's still programming in the traditional sense -- it's all data, and code that acts upon the data. The difference is simply how all of that information is defined and how you approach defining it.

Perhaps an over simplification is that traditional programming is "code, with some data structures", and object oriented programming is "data structures, with some code". Both still have data structures, and both still have code. Object oriented programming, then, is nothing more than the act of defining types of data up front, and enforcing contracts for how they communicate via sets of functions.

As you have observed, there is a huge class of applications for which this is not such a great way to implement a solution. You seem to live in a world predominately made up of such applications. In your blog post you mention looking at implementations of the "99 bottles of beer" problem (your "favorite programming showcase"). 99 bottles of beer is certainly part of that category. Trying to understand object oriented programming by looking at implementations of 99 bottles of beer is a bit like trying to understand high rise architecture by looking at a treehouse. Even a very well built tree house can only teach you so much.

TL;DR: OO programming is like traditional programming, except you focus more of your effort in defining the data structures up front, and you have those data structures communicate with each other via function pointers.

share

Not the answer you're looking for? Browse other questions tagged or ask your own question.