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

29 points by mlLK ↗ HN
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.

75 comments

[ 3.9 ms ] story [ 52.4 ms ] thread
(I'm not trying to sound condescending, so bear with me)

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

modular and re-usable components is not really OO specific tho.
That didn't answer my question though. You can technically convert any programming paradigm to anything that is touring-complete. Just because something is designed with OO methods doesn't mean that it can not be designed any other way. Original C++ compilers simply converted C++ code to C.

But seriously, if you had to write software that abstracts complexity (good), has modular components (good) and let's you attack specific problems one at a time, how would you do it? If you don't think these are worthwhile tenets of software engineering, what are, in your opinion?

Research into statically typed functional languages approaches this question, and generates some pretty good insight. It turns out that OO is sort of a religion... just one approach to modularity and abstraction. Languages like ML and Haskell provide these features in a completely non-OO style, and are very expressive and powerful.

If you are curious, look at abstract data types and polymorphism in SML/OCaml and Haskell. Also, look at Haskell's type classes, and look at SML/OCaml's module system.

Here's a paper you can read: http://www.cs.utexas.edu/~wcook/papers/OOPvsADT/CookOOPvsADT...

This is sort of resonating with me. Maybe I've been doing to many exercises by the book, I dunno, but your description of the problem space seems straight out of a textbook which I'm all to familar with. Divide and conquer; define the data set, factor, isolate, call foo, iterate. . .expressions, storage space, and iterating each as a function is not hard, in short deducing a problem set in terms of an operation is not hard for me, since an operation, to me at least, is synomous with run-time, which is why I thought I was programming. . .a compositon of operations in terms of input and output. I understand that each approach is borrowing similar tenents of refactoring input, but I don't understand how the composition of operations are playing in terms of code-time vs run-time.
I've got 8 minutes til I need to catch the bus.

The answer to your question hinges mainly on how you define components. In the Erlang language for example: It is completely functional but threads actually become somewhat stateful and ultimately end up recreating some similar scenarios for OOP programmers. On top of that, functions themselves showcase an even higher amount of reusability at times especially in functional languages because of the prevalence of lists of things and tuples. This prevents an over abundance of duplicate implementations of the same thing that, even though their signatures are identical (or nearly so) can't interoperate because they haven't been specified as exactly the same. So language wide consistency is a big plus for some functional languages.

Having said that no one tool is a golden hammer. OOP and Functional programming are just tools and there are others out there. Some not even based on Von Neumann architectures that are even more flexible than the ones we, Von Neumann proggies, are (think data flow architectures for example).

A common misconception about erlang is its degree of functional-ness. It isn't completely functional. As Peyton-Jones says, a completely functional language will just sit there and make the computer run hot[1].

Erlang is a well thought out compromise between tying your hands by restricting side effects (the monad approach) and allowing a wide audience of people to be quickly productive.

[1]: Changing the temperature of the environment can be considered a side effect thereby rendering the 100% functional language 99.999% functional.

> Having said that no one tool is a golden hammer.

Clearly you're inexperienced with golden hammer methodology, which provides both a mightier paradigm and a pleasantly horned helmet.

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

Hah! However you want!

The first few chapters of Paul Graham's `On Lisp' does a great job covering closures, which can provide elegant encapsulation. But even in Java or C++, objects aren't the only modular or reusable components - consider packages or name spaces, for example. Data types such as streams, arrays, and trees don't have to be classes, either - take a look at Haskell's data types.

Does not functional programming allow you to do just that?
Data structures with self referential code
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.

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.

I've drifted from language to language but most of time is either spent writing bash scripts, PHP, C (only if don't understand how a bash cmd), HTML, Javascript, and currently visual basic, many of you will moan at this, but I feel as if I get more out of knowing what OO is from VB than any of the other lanugages. This class wasn't by choice, it's pre-req for the school I'm in.
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 :-(

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".

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.

The smalltalk object system is a nice simple example:

    A Smalltalk object can do exactly three things:
    Hold state (references to other objects).
    Receive a message from itself or another object.
    In the course of processing a message, send messages to itself or another object.
http://en.wikipedia.org/wiki/Smalltalk#Object-oriented_progr...
Good definition. Smalltalk is the only appropriate starter language to learn objects well. Sure there is the difference between class based and prototype based languages, but this hardly matters compared to "getting" objects right in your head in the first place.
The language that fits this description best is Erlang, I would say ... (what, in this definition, is specific to objects compared to processes?)
In smalltalk everything is an object. In Erlang, many things aren't. Processes and messages are a bit higher up in Erlang's world.
Message-Oriented coding is also why commenting is so important. You don't need to know what's going on inside the method, but you do need to know what the method does, which is best accomplished through documentation.

O.O is useful to you because it makes it easier to understand your code, especially if your code base becomes very large. You can look at your code object by object rather than line by line.

O.O is useful for group projects because each member can code an object and the algorithms behind its methods individually. It also makes it easier to swap different functionality in and out.

Finally, O.O also promotes good coding practices, like reusing existing code and writing documentation. It also makes you think about your code's structure, which is crucial to keeping your code maintainable, upgradeable, readable, and reusable.

For me, writing good O.O code is a something that I learned after writing a lot of bad O.O code. So there's no reason to delay - write it and you'll see.

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).

[In a similar vein, I was about to say:]

Object-orientation is fundamentally just a way of organising programs.

In most non-OO programming, you've got a bunch of data, and a bunch of procedures that can operate on the data. The two are defined and considered somewhat separately, though they must fit together.

In OOP, a kind of datum and the operations on it are instead designed, defined and used together, as essentially linked.

I didn't quite get it either till I worked on a functional language. (btw while you're at it, take a writing class)
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.
"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)
Yes, but the writing is poor. 'bipartite' and 'homogeneous'? Would you speak to your non-academic friends that way? If not, it's not going to successfully convey the message to a wide audience.
"two part structure" & "single structure?" Ups the word count to 62
You could convey the concept of OO better in simple terms and easily stay within the wordcount. Eg.

"Programming by making things that can be interacted with in different ways"

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.

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?

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.

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.

OO is something you can't learn by reading an OO textbook. (Program!)
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.
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.
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 ...

I have sometimes thought the same thing. There are ample explanations of the use of OOP put in terms of stuff like, poodle inherits from dog, which inherits from mammal etc. or a car could be represented as a series of objects interacting with each other, the engine, gear box etc. This is all perfectly fine and super easy to visualise. But the stumbling block for me is sometimes when I try to turn these ideas to something that's actually useful. Abstact concepts that indeed do not always have a neat corelation in the real world.

If anyone has some tips on how one can begin to develop a clearer method for modeling more abstract concepts in OO, I'd love to hear them.

Try to go through the articles at: http://www.objectmentor.com/resources/publishedArticles.html

Most articles carry some example to go with the concept being explained.

Thanks for this and the other above replies.

Regarding inheritance, I once had a conversation with a "application architect" who advised staying away from inheritance until you fully grok it, because it's easy to paint yourself into a corner with it (he then disappeared before I could question him further). The only issues I could think of at the time was stuff like say you have a bird class which contains a "fly" method, with duck and emu child classes (now I'm using the dodgy animal examples :P), the duck and most other birds should be able to fly, but the emu and some others should not. What is the better practice way of dealing with this issue? And what other adverse issues can arise when using inheritance?

It has been recommended to me in the past that when it comes to systems that require more abstract objects, this is where researching design patterns would assist. However, pretty much all the design pattern literature I can find is not directly related to my current language of choice, Ruby. I can find lots of stuff talking about design patterns in Java and whatever else, which still provides some utility, but is there any books/articles that anyone can recommend on design patterns etc. using Ruby?

Think about it from OO's creator's perspective. For instance, this is what the creator of inheritance probably thought:

"All of these objects do very similar things. I don't want to have to write these functions over an over again if they're so similar..." and inheritance was born.

Most OO concepts are about writing and seeing less code. I think the best way to grasp OO is to ban ctrl+c for anything longer than 2 lines. It really forces you to think about structure and code reusability, which is what OO is all about.

I mainly use it b/c it helps to easily swap out different implementations of a generic object. Useful if I'm coding a large framework that'll be used for different problems.
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.

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).
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