Ask HN: can you summarize OO for me in 64 words or less?

I've only been writing code for so long, while I grew up designing web-sites, it really doesn't count; so, as of now, I've been invested in programming for more than four years but have never had the courage or foresight to write something in OO. However, for the past couple weeks I've been pouring myself into the OO textbooks, yet I still don't feel reassured in it's value. So, as of today I can speak OO, since I know all the jargon, but I still can't muster up the courage to write an application that seems practical to me, which is where my problem lies. I'm also no software-engineer, but I've come to face the facts that my vision of building tools/programs/output is flat; so please, inspire me with your wisdom from 30,000 feet above, metaphors, philosophy, and expression by comparison is welcome.

EDIT: I guess the origin of my writers block in doing something in OO is that I don't really feel like I'm handling real data. I feel like I'm defining and declaring spaces as I see fit, thus leading me down the path of this pseudo/pretend file-system while ignoring the platform I'm really working on. Please prove me wrong.

  • Think of it less as "Object-Oriented" and more as "Message-Oriented" and things become clear. Every object has a vocabulary of messages it can respond to. The only contract you have with the object is what it can do, not how it does it; therefore, the supplier of the object is free to implement algorithms as he sees fit. (60 words)

    Bonus analogy:

    The web itself is object-oriented. You ask a server to return a resource for a given URL; what server it is (Apache; IIS) and how the content is generated (static page; CGI; PHP) is unnecessary for the conversation.

  • "In all other languages we've considered [Fortran, Algol60, Lisp, APL, Cobol, Pascal], a program consists of passive data-objects on the one hand and the executable program that manipulates these passive objects on the other. Object-oriented programs replace this bipartite structure with a homogeneous one: they consist of a set of data systems, each of which is capable of operating on itself." - David Gelernter and Suresh J Jag (61 words)

  • Object oriented programming is definitely the way to go. OOP came about as a series of incremental improvements made to procedural programming.

    First came the idea of segmenting functionality into more manageable 'building blocks' called modules that worked together to provide the functionality of the entire system.

    Next came abstract data types which incorporated the idea of treating a set of data and the logical operations on that data as a single unit. Different ADTs were naturally stored in separate program modules.

    Next came the idea of information hiding, or separating out a module's interface from its internal structure. Information hiding serves two major purposes: a) allowing a module implementer greater freedom in changing how a module works without distrubing clients of the module and b) making it so a user does not have to understand everything about a module in order to use any part of the module.

    Having figured out modularity, abstract data types, and information hiding, programmers then turned to the task of how to better reuse code. Structured programming reduced the amount of duplicate code in a system, but still had quite a bit of code with only slight differences. Inheritance was developed as a mechanism to deal with this problem. Basically ADTs, now called classes, were arranged in a tree structure with the most general classes at the top and the most specific classes at the bottom. Several additional mechanisms were added to the system that allow child classes to have access to their parent class definitions and for runtime polymorphism.

    More than 64 words, I know. However, because seeing how OOP evolved out of the solutions to procedural programming problems helped me to understand it and see its value, it seemed like it may help you as well.

  • I remember my first class. It was a Stopwatch. It had start, stop, reset, and read methods. It maintained an internal counter by calling time(2) or something like that.

    A lot of objects have no real-world equivalent (they are not "objective", I kill myself), but that doesn't make them useless.

    Objects are an odd mash of concepts: inheritance, interfaces, global data with limited access, encapsulation, memory management. The object model will differ from language to language, and your objects will look different depending on what features you use.

    You can program in a pretty object-oriented way in straight C. Some languages bend more easily to these ideas than others.

    http://www.planetpdf.com/codecuts/pdfs/ooc.pdf [pdf]

  • This is probably the wrong community to mention this, but this discussion is an excellent example of why I am largely procedural in my programming and don't focus too much on OO. I need to tackle real world business problems. Likening objects to things like refrigerators and toasters is where I get lost. Perhaps those examples work well in the classroom to help kids wrap their heads around the concept of OO, but I just don't see how or where they fit in the real world. OO evangelists are always quick to cite a lot of technical reasons for why programming in OO offers up major benefits in their work, but (from those I've spoken to) can rarely match examples to those reasons.

  •   large automaton
      complexity is too high
      for my meager brain
    
      small automatons
      your prison cells will prevent
      intertwingling
    
      you aren't alone
      use the pneumatic tubes for
      sending messages
    
    edit: 28 words!

  • You do object oriented analysis of your problem domain. This results in a set of objects. Then you design a class hierarchy for your objects (base, child etc). Trick is to realize objects themselves do not accomplish project purpose, they just have behaviors. How you play these behaviors decides what the application finally does.

    I am surprised to see no one has mentioned the analysis part. To identify and abstract (like pulling oil well from well) "classes" of objects in your problem domain is the core proponent of OO programming. This is the basis for all data hiding and reuse.

    The OO design principles (not design patterns) tell you how to go about your class design.Check this link: http://www.objectmentor.com/resources/publishedArticles.html

    Once you have completed all your classes, you will realize how easy (and natural) it is to script the actual business logic of your application - more or less like a movie: while all the actors have their identities, the "script" tells how they interact and decides the movie experience.

  • What language are you using?

    edit: I assumed that the vast majority of languages typically used in web development incorporated some OO features. I'm interested in what is familiar to you; perhaps that will help people describe something that means something to you.

    Your question is sort of odd.

  •     class Animal
          def initialize(options = {})
            @type = options[:type]
            @name = options[:name]
            @legs = options[:legs]
            @noise = options[:noise]
          end
      
          def type?
            return @type
          end
      
          def name?
            return @name
          end
      
          def noise?
            return @noise
          end
      
          def legs?
            return @legs
          end
        end
    
        dog = Animal.new(:type => "Dog", :name => "Pipin", :legs => 4, :noise => "Woof")
        puts "#{dog.name?} the #{dog.type?} has #{dog.legs?} legs and goes \"#{dog.noise?}!\"\n"
    
        cow = Animal.new(:type => "Cow", :name => "Kevin", :legs => 4, :noise => "Moo")
        puts "#{cow.name?} the #{cow.type?} has #{cow.legs?} legs and goes \"#{cow.noise?}!\"\n"
    
    Output:

        Pipin the Dog has 4 legs and goes "Woof!"
        Kevin the Cow has 4 legs and goes "Moo!"
    
    …a simple class which turns the dog and cow variables into objects, like small boxes with information referring to that animal. By the way — I hope code isn't classed as words, else I've failed to describe it in under 64! :P

  • OO property 1: You're in a house. An appliance is a physical object that does something. A fridge is an appliance that keeps things cold, a toaster is an appliance that makes things warm, a blender is an appliance that blends things. If you change the definition of an appliance to be "a thing in a kitchen that does stuff," all of the other things that I've used "appliance" to define will still continue to be what they are, but their "scope" will be different.

    OO property 2: You've got a cookie cutter and dough. The Cookie Cutter is the constructor, it makes a object the shape of the cookie cutter insides. It looks like the shape of the cookie cutter, it smells like that shape, it _is_ that shape; but it's only really a copy of that. Which is why people have issues with "equals." Equals can refer either to having the same value, or actually being the same object.

    There are other really nice analogies (is-a vs has-a and children vs people), but I hope that my analogies make sense to y'all!

    EDIT: the above is 181 words, sorry :-(

  • Other commenters here have covered the theory well so I'll take the practical angle. OO in practice means Java and C#: procedural languages that make you organize your code as a collection of "classes", which means files. A class is a collection of related functions that you get to use after calling a "constructor", unless they're "static". Also a class can contain some data that's easily accessible to functions in this class; other classes can access it with "getters and setters", which is called "encapsulation". One class can "inherit" from another, giving you a more convenient syntax for calling functions in the "parent" class at the price of a little confusion for everyone reading the code.

    People with advanced OO skills use clever techniques to write interesting programs. For example, sometimes we want to give a class (technically, "an object of the class") to other programmers without letting them know which class we gave them. To achieve this goal, we give them another class with a function to generate objects of the first class without telling them which one. If you have trouble following, don't miss the helpful diagram: http://en.wikipedia.org/wiki/Image:Abstract_Factory_in_LePUS... An award-winning book of twenty-three such techniques is required reading for good OO programmers.

    So your gut feeling is right.

  • Complex and confusing problems can be tackled by breaking them into modules, with interfaces between. Objects are one way of doing it.

    Each object wraps up a program. The program's global variables become variables of the object. The program's functions become functions of the object. The public functions are the interface of the object (an interface is the part of a module that interacts with other modules, like the surface of an object). So basically, you have the inside of the object, and the outside (surface).

    Think of it as support for the modules that you already wanted, that seem to be naturally present in the problem, or in how you naturally want to divide it up and think about it. That is, use OO to support your conception, instead of a priestly template to mold yourself into. Tools are good slaves, poor masters. If you follow your conception, you will make mistakes - but those mistakes will belong to you, and so you will learn from them.

    Using objects for modularity does not work well for every case (e.g. I think parsing works better in the old-fashioned style).

    OO is nothing special. There's no wonderful mysterious secret. It doesn't even have a precise definition that everyone agrees on. It's just a tool. Inheritance and polymorphism are grossly overrated, but presented as a quasi-religious AI solution-to-everything - but are useful in some cases (e.g. great for windows/GUIs). There's also a danger of having overly theoretical modules - the "spaces" you mention. Be problem-driven. What does the problem need?

  • A strategy to manage complexity by decomposing problems into hierarchical type relationships through the mechanisms of encapsulation (code and data together in an "object"), polymorphism (actions on abstract types trigger behaviors without knowledge of their specific implementation), and derivation (relationships between classes) such that specific behaviors increase toward the leaves and decrease toward the roots, leaving implementation and general behavior isolated at appropriate levels.

  • What can you do with a car? Move it forward, backwards, stop, turn. Those are the methods. What features does a car have? Doors, color, age, stereo, etc. Those are the properties.

    What can you do with a string? Set it, save it, match it. What properties does it have? Length, value, encoding, language, etc.

    Object Oriented software is built with methods and properties.

    (Do I get extra credit for using 64 words exactly?)

  • The best thing about OO in app development is that it lets you abstract the main routines of your program into what is effectively business logic. For example," $customer = new cp_customer(); $customer->add($customer_form_data); /* Customer_Info => Customer_Storefront*/ $customer->link_to_storefront($SID);"

    Earlier this was a garbled mess, full of functions like custID = addCustomer(form_info) updateAddress(custID, "Billing", some_args) and so on ...

    On the flip side, OOP is trickier (b/c of encapsulation) to debug esp when object model gets complicated. In terms of programming the only way to do it better (and this is frankly v debatable, esp when you consider management of DB connections and API administration etc) is "LISP style", where you effectively concoct a DSL for your specific app.

  • Just think about it as a change in structure - all your implementation stays the same, but where the code resides gets moved around a bit. This moving around eventually ends up making your code read like a short hand walkthrough of some task, which is better than reading the code directly.

  • Computer programming is all about declaring abstractions that make computers easier to control. Objects are an intuitive way to model your program by defining logical subsets of data and operations on that data. Classes are define common, readable patterns in the data - a person class can have age, name, height and weight and methods to manipulate these. At runtime, only the values of data are replicated with pointers to single copies of methods. OOP is just another way to organize your code. Inheritance of classes gives a higher level of abstraction, allowing you to reduce the code footprint of your application and make it more maintainable.

  • Others have done well here, but I'll give it a go too, in procedural terms.

    Objects are just a style of programming. As our program begins to process different types of data, we begin to see that some data always goes together and tends to hit certain branches of code together. This is because the code and the data together form an implicit model of how a particular kind of data should be handled.

    Object orientation makes this explicit. We can store a little namespace of data in an object, and also give it a way to find the right code to run when it receives a 'message'. Then we can start to think of our program as a cascade of 'messages' between objects.

  • To respond to your other concerns:

    Are you sure you're doing it right? Maybe your design is too abstract. Beginners to OO often overdo generality and they especially overdo inheritance. If your only goal is to handle a few operations with one particular filesystem, there is no shame in writing well-commented procedural code.

    OO is not in itself a way of solving problems. It's supposed to model your problem so you can change different parts independently. So, for instance, in code modelling a filesystem, you can have code that performs a 'read()' and gets data but doesn't have to know where the blocks are or if it's talking to a pipe or an inode.

    I struggled with understanding OO for a long time too. In retrospect, one of my biggest problems was that I simply hadn't worked on systems that were large enough. I could fit all my programs in my head. When you can't fit the whole program in your head, you need strategies for knowing (not just guessing) exactly how many things your code will affect. So the idea of an object as a sort of contract emerges. You want a read() of 12 bytes from an inode to work just the same as a read() from a pipe. So you devise a sort of 'contract' that the general class of "FilePointer" has to adhere to, and then you try to fulfill that in InodeFilePointer and PipeFilePointer. Make sense?

    Where OO really takes off is in collaborating with other programmers.

    Some languages are so in love with OO, they decree that everything is an object. This can be annoying, but it's also helpful in the long run. If you're strict about it, it's impossible to write code with weird side effects or that relies on mysterious globals to communicate information. Because all state changes are captured in the object, and the object also carries around a notion of how to modify itself, you can write a new kind of object and be very sure it will Just Work.

    Once we have divided responsibilities this way it becomes possible to change our models in one part of the code without changing them in other parts. (In procedural code we might have to change the function signatures of just about every procedure in the codebase.) It's even possible to add in 'Mock' objects that just test the behaviour of other objects.

  • Software development is an exercise in managing complexity. Being able to isolate the functionality and verify the correctness is valued. OO is one attempt to make this practical in the large[1].

    Smalltalk is a great start. If you want to read more, this poorly named book is by far the best I've read on the topic: http://www.amazon.com/Software-Development-Principles-Patter...

    [1] http://en.wikipedia.org/wiki/Programming_in_the_large

  • Programming is about state (variables, constants, data), and behaviour (algorithms).

    State and behaviour are deeply intertwingled, and object orientation seeks to make programming easier by acknowledging that fact.

    Put simply: an object is something with state and behaviour, and an object-oriented programming system is one that makes working with objects easy.

    Two ways they do this are information hiding (so you can consider an object a black box and not care about its inner workings) and inheritance (when two objects are similar, you only need to specify the differences between them).

  • OO programming is great fun!

    Take a real world model and simulate it with some OO code in your favorite language.

    For instance, model an elevator system in a large apartment complex. Model the buttons, the elevators, the call buttons, the system the decides what elevator goes to which floor, etc. Those are all objects interacting with each other in some form.

    You can't hardly screw up. Mastering OO takes many years, so just get out there and starting hacking around.

    BTW, you can read all you want about driving a car, but until you sit down in the driver's seat, it isn't going to "click".

  • so this is not < 64 words and less of a description of OO and more to your solicitation of "inspire me" of why you should care about it. The critical distinction IMHO:

    Procedural programming is like a recipe- you program a sequence of instructions and while there can be if/then, loop and other logic constructs, it still runs like a "choose your own adventure" book. Since you have an imperfect view of the world and how requirements will evolve and you're providing what are essentially sequential instructions, it's brittle and unforgiving to unanticipated requirements.

    OO is less about writing instructions and more about creating a representation of the world (or at least the aspects you care about) as objects and having them interact with each other to achieve things. Because you're modeling the entities involved and having them interact rather than imposing a prescriptive set of instructions from above, it's cleaner and more resilient to unanticipated requirements.

    Granted it's overkill to use OO for simple tasks when a script will suffice. But if you're building a system that involves interaction of different entities and will need to be adapted & maintained it will almost certainly be more productive to use an OO approach. Btw, I found this book provides the most concise and useful primer on OO I've seen: http://www.amazon.com/Object-Technology-Managers-David-Taylo...

    sean

  • one good way to start seeing more objects around you is to try to search for a pattern like this one in your procedural code : a group of functions operating on a certain kind of data structure. A classic example would be the stdio functions in C. You have FILE (which is your data structure) and then fopen,fclose,fscanf etc. which are the functions operating on FILE. This is object orientation at it's most basic (an object is some data and methods to process that data) even if C is not regarded as an OO supporting language.

    There is only a small step from writing stuff like this :

    FILE* ofile = fopen("test.txt","w"); fprintf(ofile,"%s %s %s",1,2,3); fclose(ofile)

    to writing code like this :

    FILE ofile("test.txt","w"); ofile.printf("%s %s %s",1,2,3); ofile.close();

    So. you've grouped some data and some code together so it's easier to work with it. This is just the first step though, but the small objects you make will be very useful. You can make a small library of useful objects that way : file, string, date, time, point, rectangle, socket, regexp etc.

    Also, you don't have to make the whole program OO. You can keep it procedural (and for most scripts that's the case), but you can use the above objects just like you'd use their procedural counterparts before. Slowly, and with experience both with OOP and larger programs, you'll see other parts of your work that would make sense as an object. On the other hand, some of them won't. And it's perfectly ok - not all problems can be naturally modeled as a system of objects.

  • In 64 words or less:

    Start reading this and keep going until the end. In two hours or less, you will understand object-oriented programming. This is very well written and explains many differences between functional languages and object oriented languages.

    http://developer.apple.com/documentation/Cocoa/Conceptual/OO...

  • Objects combine information and operations. They should help keep disjoint things separate, and related things together. They do provide a simple metaphor for modeling.

    Not all objects are alike. Smalltalk is "pure"; Python and Ruby mostly "just work"; C++ is very complicated.

    No programming paradigm can save you from under-specification. You need a very good description of your desired behavior before you start coding.

  • • Imperialism is a business policy, in it; it has produced small, bad, unsafe increase of market, and has jeopardized the entire wealth of the nation. It is irrational from the standpoint of the whole nation, and it is rational enough from the standpoint of certain classes in the nation. A state which kept good balance-sheet of expenditures and assets would soon discard imperialism.

  • http://www.paulgraham.com/reesoo.html is a very good short survey of the OO paradigm.

  • Procedural programming concerns itself with actions acted upon the data, whereas object oriented concerns itself with data upon which actions can be applied. Think of code as verbs, and data as nouns, and procedural languages are verb oriented, object oriented are noun oriented (I talk about it at http://boston.conman.org/2004/10/19.1).

  • It's amazing that you've been able to spend four years coding without having to work on code that used object orientation. If you collaborate with others, you'll learn many useful as well as useless coding techniques and will be come a much better programmer yourself. So pick apart a few of your favorite open source projects; I'll bet you find plenty of practical object-oriented programming.

    ^ 64 words.

  • I'll do one better. I'll summarize OO in a haiku

    abstraction, hierarchy, modularity, encapsulation

    manage complexity reduces resistance to change over time

    design patterns give best practice advise

  • Why not ask Alan Kay?

    'OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.'

    He might know....

  • OO operates on ownership. The String's length, the String's text. Create a new String, and you expect it to look like a String and talk like a String.

    If there isn't an inherent ownership and hierarchy of data and data properties, OO isn't at all necessary. When the structure is well-defined though, which is in many cases, it is the most intuitive abstraction.

  • You make objects out of a directed graph of simpler objects, recursively. To answer a message they can ask their acquaintances for help, make new objects, or change their state. To an object, all that matters about other objects is how they respond to messages.

    This is more cohesive than parallel hierarchies of data structures and code that must be kept in sync.

    (63 words)

  • Data structures bound to operations on those data structures, and some obvious elaborations on that theme.

    Going much deeper gets controversial; there are many, many elaborations on that theme, each of which you can find a language that implements it and a language community that considers it anathema.

  • Model behavior and attributes of program on real-world objects. If you are programming a house, a door object would have open() and close() member methods you call on a particular Door object. Easier to work on collaborative projects by virtue of clear interface.

  • You will only appreciate what OO programming has to offer when you are doing a more complex application, of which some parts could be reusable for another one in the future. For the same reason OO is suitable for teamwork.

  • You make things, and make methods to interact with them to achieve what you want to do. The re-use of methods means more understandable code.

  • I didn't quite get it either till I worked on a functional language. (btw while you're at it, take a writing class)

  • (I'm not trying to sound condescending, so bear with me)

    How else would you write software with modular and re-usable components?

  • What is Object Oriented programming?

    I wrestled with this one in school for a while, because the name is so screwy. What is an object? It's a blob of code. It's a walled off place in your computer's RAM that has variables and functions. It's just a bit of reusable code.

    Why is that special? If you've spent your programming life copying and pasting code in a text editor, it's probably not going to be readily apparent. It's pretty easy to reuse code without having to jump through OOP hoops.

    In OOP, those reusable bits of code aren't copied and pasted, in the text editor, however. They're reused automatically in memory. When programming in an OOP style, you create one blob of code (an object), and then without touching the original, you can use the object and use it's methods and variables.

    You can modify or extend the object, and you're never changing the original object.

    For instance, in Ruby. Everything is an object. Even integers are objects and strings are objects. That is, every time I use the integer "5" in my code, I have all the methods from the Integer class available at my finger tips.

    So, I can do something like this:

       5.next  #this returns 6
       5.next.next # this returns 7
    
    Or, I can use the "times" method from the Integer class, to create a loop:

       5.times do |i|
          print i, " "
       end
          #produces
       0 1 2 3 4
    
    Why can Ruby do this? Because all integers are a type of object that has the .next() and the .times() method that we can use every time we use an integer.

    The same goes for strings. In Ruby, every string is automatically given all the methods from Ruby's String class for free. So, you can do stuff like this:

       "hello".capitalize  #this returns "Hello"
       "HELLO".capitalize  #this returns "Hello" as well
    
    and

       "hello".empty?  #returns false
       "".empty? #returns true
       "hello".length #returns the length of the string
       "hello".reverse   # returns "olleh"
    
    Every string that you use in Ruby has all the String class methods available to the programmer, because in Ruby, every string is an object.

    There are lots of other things that you can do with OOP, this is just a taste of what Ruby does. I think the key to learning OOP is to learn it in a language that uses it very elegantly like Ruby, or even Python. If you're trying to learn OOP in PHP or Perl or Java, you're in for a rather difficult time, because there's so much other stuff that gets in your way.

    But, if you learn OOP in a langauge that uses is really well, you can isolate some of the OOP concepts, and you can go back and use them in your language of choice if and when you need to.

    OOP certainly isn't the be all end all of programming paradigms, but it's well worth your while to learn if you're going to be writing code for a living. It's one way to reuse code. It's certainly not the only way.

  • OO is something you can't learn by reading an OO textbook. (Program!)

  • What kind of applications have you developed?

  • Lexical scope + hash table + closures

  • data + methods

  • nightmare :)

  • Data structures with self referential code