Подтвердить что ты не робот

Как именно "объекты общаются друг с другом путем передачи сообщений"?

В нескольких вводных текстах по объектно-ориентированному программированию я столкнулся с вышеприведенным утверждением.

Из wikipedia: "В ООП каждый объект способен получать сообщения, обрабатывать данные и отправлять сообщения другим объектам и может рассматриваться как независимая машина" с определенной ролью или ответственностью".

Что именно означает выражение в коде?

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..
    }
}
4b9b3361

Ответ 1

Если мы говорим о ООП, то термин "передача сообщений" происходит от Smalltalk. В нескольких словах основные принципы Smalltalk:

  • Объект - это базовая единица объектно-ориентированной системы.
  • Объекты имеют собственное состояние.
  • Объекты общаются путем отправки и получения сообщений.

Если вы заинтересованы в Smalltalk, посмотрите Pharo или Squeak.

Java/С#/С++ и многие другие языки используют немного другой подход, вероятно, полученный из Simula. Вы вызываете метод вместо передачи сообщения.

Я думаю, что эти термины более или менее эквивалентны. Может быть, единственное интересное отличие состоит в том, что передача сообщений (по крайней мере, в Smalltalk) всегда зависит от динамической отправки и позднего связывания, тогда как в случае вызова метода можно также использовать статическую отправку и раннее связывание. Например, С++ (AFAIK) выполняет раннее связывание по умолчанию, пока не появится "виртуальное" ключевое слово...

В любом случае, независимо от того, какой формализм использует ваш язык программирования для связи между двумя объектами (передача сообщений или вызов метода), он всегда считал хорошим стилем ООП запрещать прямой доступ к переменным экземпляра в терминологии Smalltalk или членам данных в терминологии С++ или любой термин используется в вашем языке программирования.

Smalltalk напрямую запрещает доступ к переменным экземпляра на уровне синтаксиса. Как я уже упоминал выше, объекты в программе Smalltalk могут взаимодействовать только путем передачи/приема сообщений. Многие другие языки допускают доступ к переменным экземпляра на уровне синтаксиса, но он считается плохой практикой. Например, знаменитая Эффективная версия С++ содержит соответствующую рекомендацию: Пункт 22: объявить членов данных частным.

Причины:

  • синтаксическая согласованность (единственный способ для клиентов получить доступ к объекту через функции-члены или передачу сообщений);
  • более точный контроль над доступностью элементов данных (вы не можете реализовать доступ, доступ только для чтения, доступ на чтение и запись и даже доступ только для записи);
  • вы можете позже заменить элемент данных, не нарушая публичный интерфейс.

Последний - самый важный. Это суть инкапсуляции - информация скрывается на уровне класса.

Точка об инкапсуляции важнее, чем может показаться на первый взгляд. Если вы спрячете свои данные от своих клиентов (т.е. Инкапсулируйте их), вы можете гарантировать, что инварианты класса всегда поддерживаются, потому что на них могут влиять только функции-члены. Кроме того, вы оставляете за собой право впоследствии изменить свои решения по реализации. Если вы не скрываете таких решений, вы скоро обнаружите, что даже если вы владеете исходным кодом для класса, ваша способность изменять что-либо публичное чрезвычайно ограничена, потому что слишком много клиентского кода будет нарушено. Общественные средства, неинкапсулированные и практически говорящие, неинкапсулированные средства неизменяемы, особенно для широко используемых классов. Однако широко используемые классы больше всего нуждаются в инкапсуляции, потому что именно они могут извлечь наибольшую пользу из возможности заменить одну реализацию лучшей.

(с) Скотт Майерс, эффективный С++: 55 конкретных способов улучшить ваши программы и проекты (3-е издание)

Ответ 2

Не совсем ответ на ваш вопрос, но небольшое отступление от отправки сообщений против вызова метода:

Термин сообщение относится к тому факту, что вы не знаете, какой метод будет вызван из-за полиморфизма. Вы просите объект что-то сделать (отсюда термин message), и он действует соответствующим образом. Термин метод invocation вводит в заблуждение, поскольку он предлагает вам выбрать один точный метод.

Термин сообщение также ближе к реальности динамического языка, где вы действительно можете отправить сообщение, которое объект не понимает (см. doesNotUnderstand в Smalltalk). Тогда вы не можете действительно говорить о вызове метода, если нет соответствующего соответствия, и отправка сообщения не удастся. В статическом типизированном языке эта проблема предотвращается.

Ответ 3

"Передача сообщения" - это абстракция.

Сегодня большинство языков OO реализуют эту абстракцию в виде вызова функции. По признаку я имею в виду метод операцию (см. Ниже), свойство или что-то подобное. Bertrand Meyer в OOSC2 утверждает, что вызов функции является базовой единицей вычисления в современных языках OO; это совершенно правильный и последовательный способ реализации старой абстрактной идеи о том, что "объекты общаются путем передачи сообщений".

Возможны другие методы внедрения. Например, объекты, управляемые некоторыми системами промежуточного программного обеспечения, обмениваются данными путем передачи сообщений через средство очереди.

Вкратце: не путайте абстракции с кодом. В прежние времена программисты часто заботились о теории, потому что программирование едва существовало как основная профессия. Сегодня большинство программистов редко знакомы с теорией кода.: -)

Кстати, и для теории, наклонной, ориентированные на агенты методы моделирования и программирования часто подчеркивают передачу сообщений как механизм связи между агентами, утверждая, что она происходит от теория речевого акта. Здесь не задействован метод.

Edit. В большинстве языков OO вы вызываете операции, а не методы. Это механизм выполнения, который решает, какой конкретный метод вызывается в качестве ответа на вызванную операцию. Это позволяет реализовать так часто упоминаемые механизмы полиморфизма. Этот маленький нюанс обычно забывается обычным языком, когда мы говорим о "вызове метода". Однако это необходимо для того, чтобы различать операции (как функции, реализующие передачу сообщений) и методы (как конкретные версии указанных операций).

Ответ 4

Они ссылаются на то, что клиент может вызывать метод на принимающем объекте и передавать данные этому объекту, но этот объект может самостоятельно решить, что делать с этими данными, и поддерживать свое собственное состояние по мере необходимости.

Клиентский объект не может напрямую манипулировать состоянием получающего объекта. Это преимущество инкапсуляции: получающий объект может принудительно выполнить собственное состояние и изменить его реализацию, не затрагивая, как клиенты взаимодействуют с ним.

Ответ 5

В ООП объекты не обязательно общаются друг с другом, передавая сообщения. Они взаимодействуют друг с другом каким-то образом, что позволяет им указывать, что они хотят сделать, но оставляет реализацию этого поведения получающему объекту. Передача сообщения является одним из способов достижения этого разделения интерфейса от реализации. Другой способ - вызвать (виртуальный) метод в принимающем объекте.

Что касается того, какой из вызовов вашей функции-члена действительно соответствовал бы этим требованиям, это немного сложно сказать на языке-агностике. Например, в Java функции-члены по умолчанию виртуальны, поэтому ваши вызовы a.methodA() и b.methodB() будут эквивалентны передаче сообщения. Ваши (попытки) вызовы b.methodA() и a.methodB() не будут скомпилированы, потому что Java статически типизирована.

Напротив, в С++ функции-члены по умолчанию не являются виртуальными, поэтому ни одна из ваших вызовов не эквивалентна передаче сообщений. Чтобы получить что-то эквивалентное, вам нужно явно объявить хотя бы одну из функций-членов как виртуальную:

class A { 
    virtual void methodA() {}
};
Тем не менее, как бы то ни было, это в основном "различие без разницы". Чтобы понять, что это значит, вам нужно использовать некоторое наследование:
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;
}

Ответ 6

То, что вы разместили, не будет компилироваться на любом языке oop, так как methodB не принадлежит объекту A и methodA не принадлежит объекту B.

Если вы вызвали правильный метод, то оба из них - это передача сообщений объектом C:

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

Из Википедии:

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

Ответ 7

Некоторые из ранних академических работ по ОО были в терминах объектов, передающих сообщения друг другу, чтобы вызвать поведение. Некоторые ранние языки OO были написаны именно так (SmallTalk?).

Современные языки, такие как С++, С# и Java, вообще не работают. У них просто есть методы вызова кода на объектах. Это как процедурный язык, за исключением того, что в вызове передается скрытая ссылка на вызываемый класс ( "this" ).

Ответ 8

Ваш пример не будет работать с Java или Python, поэтому я исправил и аннотировал ваш основной

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(); 
  }
}

Ответ 9

передача объекта в качестве параметра методу объекта, принадлежащего к другому типу класса. таким образом вы передаете атрибут объекта другому объекту другого класса просто вызовите методы объекта другого класса. поэтому вы можете создать объект этого класса для получения информации о другом объекте другого класса. Заметка:  это не отменяет методы ok, потому что они могут быть одного и того же имени, но принадлежат к другому типу класса. методы переопределения - это наследие методов в подклассе, и вы изменяете поведение тех же методов, что и вы, для получения высшего класса. метод вызова зависит от аргументов, которые вы вставляете в метод или тип данных. система вызывает правильный метод, и они могут быть расположены в объекте суперкласса или в объекте подкласса.

многие люди задают один и тот же вопрос. когда они работают с ООП. Я рекомендую прочитать эти старые книги. понять, что такое ООП, а не научиться программировать объект, ориентированный на языке программирования, как CPP, JAVA и PHP. введение в ООП (Тимоти Буд) Объектно-ориентированное программирование: эволюционный подход  (Брэд Дж Кокс, Эндрю Дж. Номобильски) и не забывайте читать новые книги CPP Bjarne stroustrup.

#include <iostream>
#include <string>
using namespace std;

class Car{
string brand;   
public:
void setBrand(string newBrand){this->brand=newBrand;}
void Driver(){cout<<" IS DRIVING THIS CAR BRAND "<<brand<<endl;}
void Brake(){cout<<"IS BRAKING"<<endl;}
};

class Person{
private:string name;
public:
void setName(string newName){this->name=newName;}
//HERE WE CALL METHOD OF CAR CLASS AND REDEFINE METHODS NO OVERRIDE OK   
void Driver(Car objectOfClassCar){cout<<this->name<<ends;  
objectOfClassCar.Driver();}
 void Brake(string str, Car objectOfClassCar){cout<<this->name<<"  
"<<str<<ends;objectOfClassCar.Brake();}
  };

  int main(){
  Car corolla;
  corolla.setBrand("TOYOTA");   
  Person student;
  student.setName("MIGUEL");
  student.Driver(corolla);
  student.Brake("CAR",corolla);
  //it open a lot of opportunities to do the same.
  }

Ответ 10

Работает ли этот код?

В любом случае вы не в дороге...

Передача сообщений - это способ для межпроцессного общения, один из многих других. Это означает, что два (или более) объекта могут говорить только друг о друге посредством обмена сообщениями, которые должны сказать, от кого, от кого и от чего...

Вы можете видеть, что он очень отличается от разделяемой памяти, например...