views:

470

answers:

9

In several introductory texts on Object-oriented programming, I've come across the above statement.

From wikipedia, "In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects and can be viewed as an independent 'machine' with a distinct role or responsibility."

What exactly does the statement mean in code?

    class A
    { 
     methodA()
     {

     }
    }


    class B
    {
     methodB()
     {

     }
    }


class C{
main()
{
 A a=new A();
 B b=new B();
 a.methodA(); // does this mean msgs passing??
 b.methodB(); // or does this?? I may be completely off-track here..
}
}
+1  A: 

What you have posted will not compile in any oop language, as methodB does not belong to object A and methodA doesn't belong to object B.

If you called the correct method, then both of these are message passing by object C:

a.methodA();
b.methodB();

From wikipedia:

The process by which an object sends data to another object or asks the other object to invoke a method.

Oded
This was a trick question, as a doesn't have a methodB() :)
extraneon
And b doesn't have methodA()! =)
kemiisto
@extraneon - good spot. I assumed a typo from the OP.
Oded
@kemiisto - answer corrected...
Oded
A: 

Your example won't work with Java or Python, so I have corrected and annotated your main

class C{
  main()
  {
   A a=new A();
   B b=new B();
   a.methodA(); // C says to a that methodA should be executed
   // C says to b that methodB should be executed
   // and b says to C that the result is answer
   answer = b.methodB(); 
  }
}
extraneon
+4  A: 

They're referring to the fact that a client can invoke a method on a receiving object, and pass data to that object, but that object can decide autonomously what to do with that data, and maintain its own state as required.

The client object can't manipulate the state of the receiving object directly. This is an advantage of encapsulation - the receiving object can enforce its own state independently and change its implementation without affecting how clients interact with it.

Brian Agnew
Agreed in principle, although in everyday use I would say that the term "message passing" has a more specific meaning, i.e. the way it is used in Smalltalk. See also http://en.wikipedia.org/wiki/Message_passing
Robert Harvey
"a client can invoke a method on a receiving object, and pass data to that object.." pass data as in pass parameters to that method, and the method definition decides what to do with the passed data. Is this correct?
Zaki
@Zaki - yes. Exactly.
Brian Agnew
A: 

Does that code works?

Anyway you're out of the road...

Message passing is a way for interprocess communication, one among many others. It means that two (or more) object can only speak one each other by messaging, which should say from who, to who, and what...

You can see it's very different from shared memory, for example...

Enrico Carlesso
I've also seen other texts use the term "message passing" when talking about OO, although I've never heard that here or from other programmers. I think it was a terminology used early in the OO days.
prestomation
No. Message passing is general OO practice. Take a look at Smalltalk.
kemiisto
The OP is trying to understand OOP.
Maggie
Right. I never heard about message-passing in OO programming!
Enrico Carlesso
From what I've studied, "message passing" refers to a perspective taken by Smalltalk and Objective-C (whose design was heavily influenced by Smalltalk). In these languages, objects are sent messages via the following syntax:[myObject aMessage:aParameter];Which is synonymous to (in Java for example):myObject.aMessage(aParameter);In Objective-C you are "sending a message" while in Java you are "calling and instance method"
Mark S
thats what i thought, instances of classes calling instance methods, as simple as that.
Zaki
@Mark S, you should probably have your comment as an answer, it really lays it out straight, certainly helpful, so that I could +1.
Zaki
+1  A: 

Some of the early academic work on OO was in terms of objects passing messages to each other in order to invoke behavior. Some early OO languages were actually written that way (SmallTalk?).

Modern languages like C++, C# and Java do not work that way at all. They simply have code call methods on objects. This is exactly like a procedural language, except that a hidden reference to the class being called is passed in the call ("this").

John Saunders
+3  A: 

In OOP, objects don't necessarily communicate with each other by passing messages. They communicate with each other in some way that allows them to specify what they want done, but leaves the implementation of that behavior to the receiving object. Passing a message is one way of achieving that separation of the interface from the implementation. Another way is to call a (virtual) method in the receiving object.

As to which of your member function calls would really fit those requirements, it's a bit difficult to say on a language-agnostic basis. Just for example, in Java member functions are virtual by default, so your calls to a.methodA() and b.methodB() would be equivalent to passing a message. Your (attempts a) calls to b.methodA() and a.methodB() wouldn't compile because Java is statically typed.

On the contrary, in C++, member functions are not virtual by default, so none of your calls is equivalent to message passing. To get something equivalent, you'd need to explicitly declare at least one of the member functions as virtual:

class A { 
    virtual void methodA() {}
};

As it stands, however, this is basically a "distinction without a difference." To get some idea of what this means, you need to use some inheritance:

struct base { 
    void methodA() { std::cout << "base::methodA\n"; }
    virtual void methodB() { std::cout << "base::methodB\n"; }
};

struct derived { 
    void methodA() { std::cout << "derived::methodA\n"; }
    virtual void methodB() { std::cout << "derived::methodB"; }
};

int main() { 
    base1 *b1 = new base;
    base2 *b2 = new derived;

    b1->methodA();   // "base::methodA"
    b1->methodB();   // "base::methodB"
    b2->methodA();   // "base::methodA"
    b2->methodB();   // "derived::methodB"
    return 0;
}
Jerry Coffin
+5  A: 

If we are talking about OOP than the term "message passing" comes from Smalltalk. In a few words the Smalltalk basic principles are:

  1. Object is the basic unit of object-oriented system.
  2. Objects have their own state.
  3. Objects communicate by sending and receiving messages.

If you are interested in Smalltalk take a look at Pharo or Squeak.

Java/C#/C++ and many other languages use slightly different approach probably derived from Simula. You invoke a method instead of pass a message.

I think this terms are more or less equivalent. May be the only interesting difference is that message passing (at least in Smalltalk) always rely on dynamic dispatch and late binding while in the case of method invocation one can use static dispatch and early binding too. For example, C++ (AFAIK) does early binding by default until "virtual" keyword appears somewhere...

Anyway, regardless of which formalism do your programming language use for communication between two objects (message passing or method invocation) it's always considered a good OOP style to forbid direct access to instance variables in Smalltalk terminology or data members in C++ terminology or whatever term is used in your programming language.

Smalltalk directly prohibits access to instance variables at the syntax level. As I mentioned above objects in Smalltalk program can interact only by passing/receiving messages. Many other languages allow access to instance variables at the syntax level but it's considered a bad practice. For example, the famous Effective C++ book contains the corresponding recommendation: Item 22: Declare data members private.

The reasons are:

  • syntactic consistency (the only way for clients to access an object is via member functions or message passing);
  • more precise control over the accessibility of data members (you can implement no access, read-only access, read-write access, and even write-only access);
  • you can later replace the data member without breaking your public interface.

The last one is the most important. It's the essence of encapsulation - information hiding on the class level.

The point about encapsulation is more important than it might initially appear. If you hide your data members from your clients (i.e., encapsulate them), you can ensure that class invariants are always maintained, because only member functions can affect them. Furthermore, you reserve the right to change your implementation decisions later. If you don't hide such decisions, you'll soon find that even if you own the source code to a class, your ability to change anything public is extremely restricted, because too much client code will be broken. Public means unencapsulated, and practically speaking, unencapsulated means unchangeable, especially for classes that are widely used. Yet widely used classes are most in need of encapsulation, because they are the ones that can most benefit from the ability to replace one implementation with a better one.

(с) Scott Meyers, Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)

kemiisto
In c++,java,C#, invoking a method itself implies mesage passing i guess.
Zaki
@Zaki: I edited my answer to clarify some points. Hope this helps.
kemiisto
+1  A: 

Not exactly an answer to your question, but a little digression about message dispatch vs. method invocation:

The term message refers to the fact that you don't know which method will be invoked due to polymorphism. You ask an object to do something (hence the term message) and it acts accordingly. The term method invocation is misleading as it suggest you pick one exact method.

The term message is also closer to the reality of dynamic language, where you could actually send a message that the object doesn't understand (see doesNotUnderstand in Smalltalk). You can then not really speak of method invocation given that there is none matching, and the message dispatch will fail. In static typed language, this problem is prevented.

ewernli
+3  A: 

"Passing a message" is an abstraction.

Most OO languages today implement that abstraction in the form of feature invocation. By feature I mean a method an operation (see edit below), property or something similar. Bertrand Meyer in OOSC2 argues that feature invocation is the basic unit of computation in modern OO languages; this is a perfectly valid and coherent way to implement the old abstract idea that "objects communicate by message passing".

Other implementation techniques are possible. For example, objects managed by some middleware systems communicate by passing messages via a queue facility.

In summary: don't confuse abstractions with code. In the olden days, programmers used to care a lot about theory because programming barely existed as a mainstream profession. Today, most programmers are rarely familiar with the theory behind the code. :-)

By the way, and for the theory inclined, agent-oriented modelling and programming approaches often emphasise message passing as a communication mechanism between agents, arguing that it derives from speech act theory. No method invocation is involved here.

Edit. In most OO languages, you call operations rather than methods. It is the runtime engine which decides which particular method to invoke as a response to the operation that you have called. This enables the implementation of the so often mentioned mechanisms of polymorphism. This little nuance is usually forgotten in routine parlance when we refer to "calling a method". However, it is necessary in order to differentiate between operations (as features that implement message passing) and methods (as specific versions of said operations).

CesarGon
+1, thanks for the info.
Zaki
You're welcome. :-)
CesarGon