在几本有关面向对象编程的介绍性文本中,我遇到过上述陈述。
来自维基百科,“在 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,那么术语“消息传递”来自短暂聊天 http://en.wikipedia.org/wiki/Smalltalk。简而言之,Smalltalk 的基本原则是:
-
Object是面向对象系统的基本单元。
- 物体有自己的state.
- 对象通过发送和接收进行通信messages.
如果您对 Smalltalk 感兴趣,请查看Pharo http://www.pharo-project.org/home or Squeak http://www.squeak.org/.
Java/C#/C++ 和许多其他语言使用略有不同的方法,可能源自Simula http://en.wikipedia.org/wiki/Simula. You 调用一个方法而不是传递消息。
我认为这些术语或多或少是等效的。唯一有趣的区别可能是消息传递(至少在 Smalltalk 中)始终依赖于动态分派和后期绑定,而在方法调用的情况下,也可以使用静态分派和早期绑定。例如,C++(据我所知)默认情况下会进行早期绑定,直到“virtual”关键字出现在某处......
无论如何,无论您的编程语言使用哪种形式来在两个对象之间进行通信(消息传递或方法调用),它始终被认为是一种良好的 OOP 风格,以禁止直接访问 Smalltalk 术语中的实例变量或 C++ 术语中的数据成员或任何术语在您的编程语言中使用。
Smalltalk在语法层面直接禁止访问实例变量。正如我上面提到的,Smalltalk 程序中的对象只能通过传递/接收消息进行交互。许多其他语言允许在语法级别访问实例变量,但这被认为是一种不好的做法。例如,著名的有效的C++ https://rads.stackoverflow.com/amzn/click/com/0321334876书中包含相应的建议:第22项:声明数据成员私有。
原因是:
- 语法一致性(客户端访问对象的唯一方法是通过成员函数或消息传递);
- 更精确地控制数据成员的可访问性(可以实现无访问、只读访问、读写访问、甚至只写访问);
- 您稍后可以替换数据成员,而不会破坏公共接口。
最后一项是最重要的。这就是本质封装- 隐藏在班级级别的信息。
关于封装的一点比最初看起来更重要。如果您对客户端隐藏数据成员(即封装它们),则可以确保始终维护类不变量,因为只有成员函数可以影响它们。此外,您保留稍后更改实施决策的权利。如果您不隐藏此类决定,您很快就会发现,即使您拥有某个类的源代码,您更改任何公共内容的能力也受到极大限制,因为太多的客户端代码将被破坏。 public 意味着未封装,实际上,未封装意味着不可更改,特别是对于广泛使用的类。然而,广泛使用的类最需要封装,因为它们是最能从用更好的实现替换一种实现的能力中受益的类。
(с) Scott Meyers,《Effective C++:改进程序和设计的 55 种具体方法》(第 3 版)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)