Sister page of AlternateObjectOrientedProgrammingView for discussion. ---- ''Encapsulation is completely irrelevant to ObjectOrientedProgramming. It's essentially a set of scoping rules and access restrictions which are possible when OOP is weakened. Encapsulation says that code and data are packaged together: that methods are associated with a class.'' I find this statement rather contestable. Encapsulation as a principle when considered at different levels (not just the normal "data" encapsulation sense) actually leads into other principles like polymorphism and inheritance. As such I cannot see how you can firstly go on about inheritance etc, and then later on say the Encapsulation is completely irrelevant to ObjectOrientedProgramming. For a more complete explanation of this point of view see http://www.netobjectives.com/resources/downloads/Encapsulation_1stPrinciple_OODesign.pdf ---- Alan Kay (the inventor of object oriented programming, said that messages and encapsulation were the most defining features of OOP. I agree. We all know what a variable is but what is a collection or variables? In C, that collection is a "structure". If an "object" isn't the encapsulation of multiple "variables" then why not just use the word "variable"? If methods aren't associated with this structure of variables, then why use the word "object" when "struct" would do? The association (encapsulation) of a group of variables with the programs (methods) that look after those variables, to me, is the fundamental definition of an "object". No objects, no OOP. If you think an "object" is just code, then call it a "function". If you think an "object" is just data, then call it a "structure". If you have data and code, it is called a "program". If you have multiple programs that must communicate with each other to accomplish their useful function, then you can call these programs, objects (unless you would like to re-define your own personal language). Message passing "objects" is the central idea that was meant by "object oriented" programming and implemented in Smalltalk. Although I like polymorphic functions, inheritance, etc very much, these aren't essential for OOP. -- DavidClarkd : Association isn't encapsulation: encapsulation means the data cannot be accessed directly, but only through GateKeepers. -- Gremnebulin. ----------------- The only stable OO concepts are polymorphism, and user-defined types: that you can define some type out of simpler types, give it a name, and treat instances of different types uniformly. If we implement the "same" OO design in say EiffelLanguage, PythonLanguage, CeePlusPlus, SmalltalkLanguage and CommonLisp, the only commonality will be that we define some classes and methods, instantiated objects, and that we use some generic syntax to apply what appears to be a common operation to different types, backed by specialized methods that we write ourselves. : Not strictly true, as there are classless OO languages -- Gremnebulin. ''You think encapsulation changes a lot? I don't see it. Basically, one needs to be able to create an object which has a bunch of functions acting on data or other objects. It is an extension of the old 'module'/'library' concept but with a finer-grained scope. 'Private' variables are nice to have, but are dispensable. I suspect the dissonance here relates to the top-down versus bottom-up view of OO. I am very much a bottom-up viewer, which has been somewhat unfashionable until recently.'' In the CommonLispObjectSystem solution, you would not have an object which "has" a bunch of functions. ---- AlternateObjectOrientedProgrammingView is nice but who cares what OOP really is? You know it when you're doing it. -- AndrewQueisser ---- Assuming you are rational, you must have a reason for knowing that whatever you are doing is OOP, and that reason stems from having a definition of OOP which corresponds to what you are doing. You might not be able to fully articulate that definition, and you might bend it to suit what you are doing at the moment. But nevertheless, what you believe OOP to be determines on what you are actually doing in that moment when you are doing it and know it. AQ: ''I agree here. It's just that OOP is not a scientific term. It's like trying to define what a car is. Does it have to have 4 wheels? Does it have to have a steering wheel? I've followed countless pointless discussions on what OOP is. It's obviously a matter of opinion.'' Moreover, as a programmer, you may be required to produce designs and code that satisfies the principles of OOP. Suddenly, the definition of OOP becomes very important, because it affects how you do your work so that it meets the requirements. You may "know" that what you are doing is OOP, but that means nothing if you are unable to make a convincing argument that will allow someone else to know what you know. You will go from not caring to caring in a few seconds flat! If an overly strict version of OOP containing a mishmash of irrelevant rules is forced upon you, that can make your life more difficult, therefore it's in your best interest to get everyone to agree on a version of OOP that gets out of your way as much as possible. AQ: ''Luckily I never have to convince anyone that I'm doing OOP. We've never any requirement of that sort.'' ''But you may be indirectly required to do this by way of a requirement to produce UML (UnifiedModelingLanguage) diagrams. And UML pushes an orthodox, single-dispatch, encapsulated view of OOP.'' Another reason why the definition of OOP is important is that it influences the design of programming languages; at least those ones which are geared toward the lowest common denominator. The principle of least surprise is to create a language which agrees with the popular definition. This creates a cycle which entrenches a particular view. If you believe that OOP is about putting methods with classes, dispatching on an object, and having a set of scoping rules that bring about encapsulation, and millions of others believe the same thing, chances are that you are going to continue to be subjected to programming languages which reinforce your belief, since you are not able to express the demand for anything else, and if you are one of the few who are able, you are still stuck with the tools. AQ: ''This is just pure elitism. If you don't like what the huddled masses are doing there are probably better ways to be a missionary than quibbling over what OOP is.'' I have a definition of OOP that is more broadly encompassing. I'm not rejecting programs that only use single dispatch or encapsulation from being object-oriented. More inclusive means less elitist. AQ: ''Sorry, I thought when you said "IN any case, it's clear that a particular kind of PolyMorphism is the defining concept in ObjectOrientedProgramming." You meant to exclude programs that use single dispatch or encapsulation from being OO.'' If they use single dispatch, then they are polymorphic. But I would exclude programs from being OO if they don't have any polymorphism. But then so would the more commonly accepted definition of OO, which has polymorphism in its list of ingredients also. ---- Someone has a quibble that is moved here: CirclesAintEllipses. This is a very weak point, because circles can be ellipses if you want them to be, different geometric spaces notwithstanding. If circles are to have a special representation that is distinct from ellipses, they can well have that, and yet be derived from ellipses. In CommonLisp implementations, an integer is not typically implemented as a two-element ratio object in which the denominator is one. Yet, you can apply the NUMERATOR and DENOMINATOR functions to an integer value; the type-specific "methods" behind these functions do the right thing, even though the object doesn't have any such artifacts in its bitwise representation. In the language of the CirclesAintEllipses page, an integer doesn't necessarily have the "ontology" of possessing a numerator and denominator, yet the is-a relationship can work regardless. Or it's possible to have an implementation in which a ratio object with equal numerator and denominator serves as an alternate representation for an integer. When you ask such an object what its type is, it can assert "I am of type integer". Objects that appear to be instances of the same class don't all have to have the same representations. All the published methods have to work seamlessly across all of them, that is all. Let's call this a PolyType. ("Polymorphic''''''Type" was originally suggested, but that means something else. The name needs to convey the idea of multiple representations giving rise to the same type at a higher level.) ---- ''If you ask most programmers what object-oriented programming is, they usually regurgitate something about polymorphism, encapsulation, inheritance, methods that belong to classes, objects that "receive" method calls or messages, and such.'' ''In its barest essence, object-oriented programming revolves around one simple idea: that an expression in a program, consisting of a function and one or more arguments, can stand for multiple implementations.'' Where is the "object" in this definition of OOP? An "object" is a combination of data and code. I see nothing in OOP that says you ''must'' have polymorphism or to what degree it is implemented! Why would you call something "Object Oriented" and leave out the "object" part? -- DavidClarkd : Class-based OO is a special case of OO, is a special case of type-based polymorphism, is a special case of polymorphism. Objects without polymorphism don't *do* anything special at run-time-- at best, they are a convenient way of packaging and viewing related code and data. -- Gremnebulin. I have been in the industry since the birth of commercial "Object Oriented" programming in 1980. I was there, and these statements differ wildly from my first-hand experience, reflecting at best an inside-out implementation-driven view of what "Object Oriented" meant and means. The folks at XeroxParc, primarily AlanKay and DanIngalls, created the term with a simple and straightforward metaphor and idea: replace the "verb object" syntax of seventies-style command line interfaces (such as Unix's "ksh" and "csh") with the compellingly simpler "object verb" syntax of SmalltalkLanguage. The premise is very simple: select an object and then do something to it. Hence the phrase "Object Oriented". The selection of the object limits the scope of the verbs that may be applied to it, thus simplifying life for both the user and the developer. All the crappola about polymorphism, encapsulation, inheritance, and so on came much later. An Object-Oriented system is a system in which the basic idiom is to identify an object and then act upon it. I agree. I think I said this elsewhere, but OO seems only to rest on encapsulation in the weak sense that we are building coherent objects that interact to express a computing system. The rest is stylistic elaboration. -- RH. When methods stand alone separately from classes, then you no longer (necessarily) have coherent objects that interact. Objects are then just data structures, and it is methods that interact. ''Just like CeeLanguage then''. ''No, objects don't know their own type in CeeLanguage. There is no inheritance, not to mention multiple. There is no polymorphism at all other than what the programmer hacks up with the use of type fields and unions or whatnot. By the way, TomLord proposed some extensions to C to do object-oriented programming using generic functions and methods with multiple dispatch. He calls it Pico C.'' see http://regexps.srparish.net/www-ancient/labnotes/devo-meta-x/view-topic/PicoC/IntroTopic. Unfortunately the links on this page still point to the old www.regexps.com which doesn't exist. The content is actually all there, but the URL's need to be edited from www.regexps.com to regexps.sprparish.net! You can still have the illusion that objects interact if you want. Specialize only the leftmost parameter of a method. In languages with LexicalClosure''''''s, there is less need to do this with the object system; if you want to combine code and data into a capsule, you rip it directly out of the program's body and lexical environment by making a closure. Closures are the appropriate vehicle for encapsulation, because they just reuse the protection mechanism of lexical scope: that a function's parameters and local variables are private data, as expressed by the physical nesting of expressions. : Closures are extremely limited in interface. They are more akin to functional objects than objects in general. -- Gremnebulin. ---- You know, I don't get the difference between '(thing1 thing2 thing3)' and 'thing (thing2 thing3)'. Are they conceptually different? Both require an implied global container. So we can create an equivalence: thing1(thing2 thing3) -> Container(thing1 thing2 thing3) (thing1 thing2 thing3) -> Container(thing1 thing2 thing3) This suggests that we can transform one language into another without any problems at all. Perhaps one might need to juggle the order of the arguments and make some arbitrary partition of function into object. Is there a counterexample? Now, for me, the interesting bit of OO is when we have physically separated entities, which essentially define the hardest of hard scopes. Then the containers must become explicit, and probably multiple. At that point we have a specific reason to do OO, which I think is what an object was meant to be in SimulaLanguage, and even was in SmalltalkLanguage to some degree, i.e., the Object was physically motivated. If you remove this physical requirement for scope, then it appears to be a matter of aesthetic. So I would say scope is the fundamental attribute of an object. Everything else is gravy. -- RichardHenderson ------ I'm not sure I agree with the view that encapsulation weakens object-oriented programming, and I think that this is best explained starting with the article's observation about CeePlusPlus's model: "any correct C++ program which uses these access rules can have them removed. The result is also a correct C++ program which does exactly the same thing." The point of encapsulation isn't to associate methods with data (though it often works toward this end). It isn't to separate implementation from interface (though again, it is useful for organizing code which does). The purpose of encapsulation is to give the programmer a tool with which to reason about program correctness--- to provide a strong guarantee of consistent object state. That is, the purpose of encapsulation is ''not'' to effect or to impose any transformation upon a correct program, but is instead to ''prevent incorrect programs''---that is, programs which are well-formed but which violate the high-level semantics of a user-defined programming construct---from being accepted by the implementation. The author says, "Encapsulation does not reduce programming errors. Rather, it identifies certain programming situations which are not defects, and declares them to be defects," and in doing so neatly misses the point that the entire purpose of declaring those situations to be defects is precisely that they ''are'' programming errors, and not simply ill-formed constructs. To under-allocate a buffer ''is'' an error, to fail to update a parent pointer ''is'' an error, and to fail to NULL out a next pointer ''is'' an error, and more importantly, they are errors which are ''ubiquitous'' and which the implementation in general ''cannot'' diagnose. In transforming these errors from elusive run-time corruption bugs or segfaults which occur miles from the point at which they were committed into compile-time access violations, programming errors can be ''massively'' reduced. As for using member functions and access specifiers to implement encapsulation, it all comes down to language semantics. Fundamentally, what is necessary for encapsulation is a mechanism by which one can restrict access to fragile object state to a fixed, controlled set of code. Encapsulation could just as well be achieved with packages/modules, only allowing code within the same module as an object's class to modify its contents. However, this gives the programmer far less fine-grained control over just what code can modify what state and requires getters and setters (for which there are arguments both for and against) for "robust" members (i.e., those whose state needn't be managed to maintain class invariants). At any rate, encapsulation does not "weaken" OOP. In fact, it is an absolute necessity; OOP is predicated on the notion of polymorphism, whether static or dynamic, as the article duly notes. Naturally, two different types which can be interchanged in a polymorphic construct possess distinct implementations; otherwise, there would be no reason for two different types (well, this isn't strictly true; strong typedefs would make a valid counterpoint, but they hardly constitute the majority of polymorphic types, even in the few languages in which they exist). Thus, ''at least'' one of the types ''must'' encapsulate its state behind the common polymorphic interface. That this presents the perfect opportunity at which to inject airtight invariant guarantees is just a bonus. ------ See also: NobodyAgreesOnWhatOoIs, DefinitionsForOo