Language agnostic “你到底是怎么做的?”;对象通过传递消息相互通信;?

Language agnostic “你到底是怎么做的?”;对象通过传递消息相互通信;?,language-agnostic,oop,Language Agnostic,Oop,在几篇关于面向对象编程的介绍性文章中,我遇到了上面的陈述 在维基百科中,“在OOP中,每个对象都能够接收消息、处理数据和向其他对象发送消息,并且可以被视为具有不同角色或职责的独立“机器” 该语句在代码中的确切含义是什么 class A { methodA() { } } class B { methodB() { } } class C { main() { A a=new A(); B

在几篇关于面向对象编程的介绍性文章中,我遇到了上面的陈述

在维基百科中,“在OOP中,每个对象都能够接收消息、处理数据和向其他对象发送消息,并且可以被视为具有不同角色或职责的独立“机器”

该语句在代码中的确切含义是什么

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

您发布的内容不会用任何oop语言编译,因为
methodB
不属于object
A
methodA
不属于object
B

如果调用了正确的方法,则这两个都是通过对象
C
传递的消息:

a.methodA();
b.methodB();
来自维基百科:


一个对象向另一个对象发送数据或请求另一个对象调用方法的过程。

您的示例无法使用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(); 
  }
}

它们指的是这样一个事实:客户端可以调用接收对象上的方法,并将数据传递给该对象,但该对象可以自主决定如何处理该数据,并根据需要维护自己的状态

客户端对象不能直接操作接收对象的状态。这是封装的一个优点-接收对象可以独立地强制执行自己的状态并更改其实现,而不会影响客户端与它的交互方式。

这段代码有效吗

不管怎么说,你已经离开了这条路

消息传递是进程间通信的一种方式。这意味着两个(或多个)对象只能通过消息传递彼此说话,消息传递应该是从谁、到谁、什么


你可以看到它与共享内存有很大的不同,例如…

关于OO的一些早期学术工作是在对象之间传递消息以调用行为方面。一些早期的OO语言实际上就是这样写的(SmallTalk?)


现代语言如C++、C语言和java语言根本不工作。它们只是在对象上有代码调用方法。这与过程语言完全相同,只是调用中传递了对被调用类的隐藏引用(“
This
”)。

在OOP中,对象不一定通过传递消息相互通信。它们以某种方式相互通信,允许它们指定要执行的操作,但将该行为的实现留给接收对象。传递消息是实现接口与实现分离的一种方法。另一种方法是在接收对象中调用(虚拟)方法

至于您的成员函数调用中的哪一个真正符合这些要求,从语言不可知的角度讲有点困难。例如,在Java中,默认情况下成员函数是虚拟的,因此对
a.methodA()
b.methodB()
的调用相当于传递消息。您(尝试a)调用
b.methodA()
a.methodB()
将无法编译,因为Java是静态类型的

相反,在C++中,成员函数默认不是虚的,所以您的调用都不等同于消息传递。要获得等效的功能,您需要将至少一个成员函数显式声明为虚拟:

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;
}
struct base{
void methodA(){std::cout methodB();/“派生的::methodB”
返回0;
}

如果我们谈论OOP,“消息传递”一词就来自于此。简单地说,Smalltalk的基本原则是:

  • 对象是面向对象系统的基本单元
  • 对象有自己的状态
  • 对象通过发送和接收消息进行通信
  • 如果您对Smalltalk感兴趣,请查看或

    Java/C#/C++和许多其他语言使用的方法可能与源代码略有不同。调用方法而不是传递消息

    <> P>我认为这个术语或多或少是等价的。唯一有趣的区别是消息传递(至少在SimalTalk中)总是依赖于动态调度和后期绑定,而在方法调用的情况下,也可以使用静态调度和早期绑定。例如,C++(AFAIK)在默认情况下提前绑定到“虚拟”。关键字出现在某处

    无论如何,不管您的编程语言在两个对象之间的通信(消息传递或方法调用)中使用哪种形式它总是被认为是一个好的OOP风格,禁止在C++语言术语或SimultTalk术语中直接访问实例变量,或者在编程语言中使用任何术语。 Smalltalk直接禁止在语法级别访问实例变量。正如我前面提到的,Smalltalk程序中的对象只能通过传递/接收消息进行交互。许多其他语言允许在语法级别访问实例变量,但这被认为是一种不好的做法。例如,著名的书中包含了相应的建议:项目22:宣布数据成员为私有

    原因是:

    • 语法一致性(客户端访问对象的唯一方式是通过成员函数或消息传递)
    • 对数据成员的可访问性进行更精确的控制(您可以实现无访问、只读访问、读写访问,甚至只写访问)
    • 以后可以在不破坏公共接口的情况下替换数据成员
    最后一个是最重要的,它是封装的本质——在类级别隐藏信息

    关于封装的要点比它可能更重要
    #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.
      }