views:

4181

answers:

15

I'm fairly new to programming but I've been reading some interesting discussions on StackOverflow about various programming approaches. I'm still not 100% clear on what the difference is between procedural programming and object oriented programming. It sounds like object oriented programming still uses procedures (methods) but everything is organized differently because the object is the star of the show. But it seems to me that procedures still allow you to do all of the same things. Like in C, you can put all of your similar procedures into a library. So couldn't you really say that a library in C is similar to an object in C++?

+6  A: 

The difference is that objects have procedures and related data in the same place - procedural languages use 'structs' (things that hold related data together) which keeps the data separate from the procedures. Effectively, anything you do in an OO language should be possible in a procedural language with a combination of structs and procedures.

The main difference is the mind set that an OO languages puts programmers in.

vanja.
+1  A: 

This is a simplified answer.

  • In a true OO language, the only procedural coding is done inside of an object.

  • C has no objects and C++ is a language that supports objects. Java on the other hand everything is an object(except the primitives). Everything is typed.

  • Linear progression happens inside of the objects but the objects themselves are just collections of code and data.
WolfmanDragon
'... to objects themselves are just collections of code and data.'
Richard A
@Richard, thank you for pointing out my omission. I will correct it.
WolfmanDragon
+16  A: 

You can program procedurally in most OO languages, but the power of OO comes from the ability to inherit, encapsulate and abstract that procedural logic. I think you are correct, a library should look a lot like a class. It should have its own scope and encapsulate logic behind functions with meaningful names.

Aram Verstegen
To complement your answer, inheritance, encapsulation and polymorphism are the three pillars of OOP.
facildelembrar
+4  A: 

Procedural is part of the procedural/functional/logical (or logic oriented) distinction (compare c, lisp, and prolog) between different ways of describing what a program should do.

Object orientation is orthogonal to this other idea, and describes a means of grouping sub-programs with data. C++ and java are procedural languages with object oriented features; fortran77 is a procedural languages without object oriented features. Common lisp supports object orientation; some older lisps do not. Plain vanilla prolog does not support objects, and I can't name a logic oriented language that does (I don't do logic oriented programming, it is on my list of things to do when I have some copious spare time. I barely do functional programming).

As others have noted, however, proper object oriented thinking changes how you do your programming as much as a switch from procedural to functional.


BTW-- I see "procedural" used a lot to distinguish non-object-oriented procedural languages from their object-oriented brethren, but I think this is a poor usage driven by the lack of a clean adjective for "not object oriented". YMMV.

dmckee
"logic oriented"? ;-P
Shog9
Instead of "logical" to avoid a disaster like "I can't name a logical language..."? Yeah I can see that.
dmckee
@Shog9: Is that better?
dmckee
Yeah, i like it. :-)
Shog9
+3  A: 

In a procedural program, the code is king and the data is subordinate. In other words, you have programs which act on data and they're not usually tightly bound.

In the OO world, objects are the primary thing of interest. An object consists of data and the code that is allowed to act on that data, and they are very tightly bound. It is the concept of encapsulation, the hiding of information.

An example, let's say you have a number and you want to double it. A procedural way of doing this is:

n = n * 2

The code here quite explicitly multiplies n by 2 and stores the result back into n.

The OO way of doing this is to send a "message" to the number object telling it to double itself:

n.double();

The advantage of this is called polymorphism. What happens when you decide you want to be able to double a string like "bob". In the procedural world, you'd have to provide more code to do the doubling but you'd also have to call that code differently.

With OO, you create a string object which can also take the 'double' message. The code to double a string belongs to the string object so it knows it has to act differently to the number object. If it decided that "bob" * 2 was "bobbob", the code would look something like:

class number:                    class string:
    int n                           char array s
    procedure double:               procedure double:
        n = n * 2                       s = string_join(s,s)

Then you could call x.double() no matter what actual type x was (number or string) and it would know which code to run - this greatly simplifies your code. You can double integer, strings, matrices, complex numbers, reals, window sizes on your monitor and all sorts of different things.

And you're right, a C library can be made to look a little bit like objects. The classic example is stdio.h - you don't ever care what a FILE* actually points to, just the fact that it will behave in a certain way. The FILE*, fopen(), fclose() and other functions are an class of sorts representing the I/O capabilities of C.

paxdiablo
Excellent explanation. I'm surprised this was chosen as the best answer. I think this really nailed it.
Question: I understand how your example represents the concept of polymorphism but I'm not sure how it represents encapsulation - is it because the double functionality is now wrapped up in a little modular piece of functionality called a method? As soon as we have a method, we have encapsulation?
@WO, encapsulation is the hiding of data or code. Code encapsulation is what allows polymorphism since the code now belongs to the object rather than having external code acting on an object. You tell the object what to do, not how to do it. It knows how to do it. Encaps/polymorph are closely tied.
paxdiablo
@Willem, I assume you mean "...surprised this wasn't chosen...". Thanks, but such are the vagaries of SO. The questioners decides the accepted answer, the community decides the best answer. You and I know mine is the best answer :-) but we're only two people (and I can't upvote it).
paxdiablo
There. Now there are 3. ; )
Mike Grace
This is really an excellent explanation. I think this will help a lot of my friends in an intro to OO class. I'll share it with them. Thanks for taking the time to share. :D
Mike Grace
+6  A: 

OO is mostly a mind set. You can program OO in C (if you really want to ... ), and you can perfectly have procedural code in C++/Java; what I mean is, even if you use classes on the surface, it could still be procedural.

The idea behind OO is abstraction of state. Instead of "thinking" in terms of "groupings of data", you "think" in terms of "objects", where an object is an "interface" for "grouping of data and ways to manipulate this data".

It all sounds philosophical, because it is.

There's a lot to say here, and it can't be all said in a small SO post, so I'll leave it here.

UPDATE
As mentioned in Flanagan's answer, OO languages implement constructs that utilize this abstraction.

I mean, you could technically "hack" classes and polymorphism in terms of structs, functions, and function pointers.

Here's an example of OO in C

hasen j
A: 

Lots of interesting points already mentioned here.

One way to think about it is that in OO, you have the idea of 'objects' which are things that have characteristics and behaviors inherent to them. They typically have some sort of public 'interface' which provides a mechanism to retrieve some information about them, but the object itself, or rather its 'class', limits what information is publicly available. The innards of the object are not exposed to the public because there's typically no need to know the dirty details 'under the hood' of the object. So object oriented programs utilize this construct, as well as other things.

Procedural programming doesn't typically utilize such a coupling of data and behavior into an 'object'. I've seen it done in C before but it wasn't pretty and involved way too much monkey business to approximate what one could do with, say, C++.

One of the ideas behind object oriented development is that I ought not be able to muck with your data through any means other than the ones that you've provided. If you provide me only a well-thought out interface, you can keep me honest. Now, if you are using a procedural approach and you send me a structure that has no built-in protections, well then I can do as I please and if I'm dumb or evil, I can change things you might not want me to change.

Granted, you can circumvent the object if you are clever but you've got to go out of the way to do this.

This isn't complete, but it is one aspect.

itsmatt
A: 

The way C++ is implemented just makes OO programming look a lot like procedural programming. You need to shift your thinking slightly.

In C++ objects have methods that are just procedures that act on the object. But in a real OO paradiam you should think of the methods as potential messages that the object can recieve (ie letters). The object recieves a message (the parameters represent the payload of the message ie the content of the letter) and changes its state based on the message.

Martin York
+9  A: 

IMHO, object oriented programming is a concept that exists at a higher level of abstraction than procedural programming. The two are not mutually exclusive in that individual methods in an OO program look pretty much the same as individual functions in a procedural program. This contrasts with, for example, functional programming, which requires a completely different mindset. Furthermore, you can write procedurally in an OO language by making everything static, etc. You can be a human compiler and write effectively OO code in C by using lots of function pointers and struct pointer casting.

OO, then, is more of a design philosophy and world view than something w/ a rigorous definition. It requires that inheritance, polymorphism, etc. be used as major patterns in structuring your code, and that syntax be provided to make these expressible without resorting to low-level tricks. It requires that you think of code that acts on the state of a collection of data as being a property of the data, not a procedure that exists by itself. It is not black and white. Your code can be "more" or "less" OO depending on how heavily you rely on inheritance, polymorphism, classes and the "methods as a property of data" worldview as a means of structuring and explaining/understanding your code.

dsimcha
Good point on the difference between OO code vs. procedural code and OO languages vs. procedural languages. Upped.
Eduard - Gabriel Munteanu
+4  A: 

[pardon the primer style, it's late and i'm tired]

procedures process data - data in, apply some processing, get data out

sometimes, some of the data elements are related to some of the other data elements, and it's convenient to group them together into a data structure, which can then be manipulated and addressed as a single unit.

now our procedure can take a data structure as input and alter it and/or produce another data structure as output

occasionally we notice that some procedures are only concerned with a certain kind of data structure; it is convenient to group these procedures together with their data structure, and call it an object.

a template for creating objects is called a class; an object is said to be an instance of a class

we may notice that one class is very much like another, so instead of copying and pasting code we let one class inherit from another: the subclass inherits from the superclass or "base class". In this way the subclass has access to all of the data structures and procedures of the superclass, and can augment or override them in certain ways

if we politely request an object to do something for us instead of brutally calling its procedures directly, this is called message passing, even if no actual 'message' is transmitted. The joy here is that many different kinds of objects may understand the same message, which leads to the notion of polymorphism. For example, we can ask many different kinds of documents to Print themselves, and they each respond appropriately.

a language that supports objects (via classes or not) with message passing and inheritance is called object-oriented. If there is no inheritance, the language is merely object-based.

good luck with your studies!

Steven A. Lowe
This is superb! Can't imagine what it would have been like if you hadn't been tired. I'm saving this.
@[Willem Obst]: Thanks - if I had more time, it would have been shorter ;-)
Steven A. Lowe
Wow! I wish more of my teachers could explain stuff as clearly as you have here. Thanks for your contribution!
Mike Grace
[@Mike Grace]: thank you for the high praise. I am allegedly working on a book ;-) http://stackoverflow.com/questions/303276/suggest-chapters-topics-for-oop-book
Steven A. Lowe
+2  A: 

Its easier to understand in context, look at other abstractions introduced between languages.

A key difference between assembly language and a procedural language like C or Pascal is the introduction of the "procedure" abstraction. People writing assembly code create procedures, but its hard and error prone, a procedural language gives you tools to make it easier.

The difference between a procedural language and an OO language like C++ is the "object" abstraction. People who write "c" often create conceptual objects but its difficult and error prone, an OO language gives you tools to make it easier.

Things like Sing# from Microsoft (or Erlang) add the Message/Process abstraction into the language. Sure, you can do message passing and process creation in assembly, C or C++ but Sing# makes it easier.

It all comes down to the same machine code, these abstractions are purely for the benfit of our brains, not the computer.

Mo Flanagan
+12  A: 

You are correct in your observation that object-oriented programs are based in many ways on the procedural paradigm. You are also correct in that syntactically all that really happens is that you invoke functions. In fact, you could implement many features of object oriented languages using procedural mechanisms (e.g., function pointers in C++). You could thus do an object-oriented design and still implement it in a procedural language (e.g., like old C++ compilers did).

The importance of the object oriented paradigm is not as much in the language mechanism as it is in the thinking and design process. In procedural programming the thinking is about operations and breaking those operations down using other operations, grouping them into modules, etc. This means that the data or state falls into a secondary importance. It is like thinking of mathematical operations.

The object oriented paradigm, on the other hand, says that you need to think of state and operations together as an entity, and then design your program as interactions between entities that exchange state and activate operations.

Uri
+1  A: 

It depends how you define OOP. In terms of Java-like OOP where you call methods on objects, procedural programming is pretty much the same. As far as I can tell you can emulate all OOP principles (encapsulation, abstraction, polymorphism, inheritance) in a procedural language like C. Proof of this is GObject, to some extend Objective-C, and many other OOP language implementations using C, like cPython. This is done by using structures and operating on those structures using functions:

typedef struct {
    Object *isa;
    String *name;
    Date *birthday;
} Person;

Person *Person_new();
String *Person_name(Person *self);
void Person_setName(Person *self, String *newName);
// ...

The interface is very OOP like. It doesn't really allow for polymorphism, but it's also possible. It is very similar to a Python interface, except that the attributes are separate from the "methods":

class Person(object):
    def __init__(self):
        self._name = ""
        self._age = datetime.datetime.now()

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

I chose Python for the example because "self" is explicit, as in the C example. Many OOP languages, like Java, abstract this.

There are also the Smalltalk-like OOP where messages are sent to objects, rather than calling methods on objects. The difference is subtle at first glance, but it provides a lot of power and flexibility. This can also be implemented in procedural-languages, as proven by Objective-C.

Object-oriented programming is not necessarily a type of language, but rather a paradigm. Object-oriented languages such as Java, Python, Ruby, etc, provide syntactic sugar to easily manipulate objects, and this is the main difference between "procedural languages" and "object-oriented languages".

Indeed, a library, or rather a set of functions operating on a structure, is the same as an object in C++. In fact C++ is implemented in just that way.

sebnow
A: 

For a fairly in-your-face example of the difference between procedural and OO, try learning Smalltalk. In Smalltalk, everything, and I mean everything is an object. There are no if-statements or while-loops. You achieve that functionality by sending messages to (a.k.a. invoking methods on) other objects. It really makes your head spin at first, but I think you'll quickly grok what OO is supposed to be.

moffdub
+7  A: 

The difference between the two is subtle but significant.

In a procedural program, modules interact by reading and writing state that is stored in shared data structures.

In an object oriented program, modules in the form of objects interact by sending messages to other objects.

Serx