面向对象是如今大多数代码基的基本构建方式。常规了解的面向对象包括封装、继承、多态。但今天,重新审视一下这三个特征。
封装,之前往往说的是把数据和方法集中在一起,以访问限定符,限定数据和方法的外部访问权限。这没有错,但不根本。封装,应该是一个对象,自己管理自己的状态,而不应由别人管理。更严格点,对象自己保管的数据,归自己所有,其他外部无权改变其内部任意数据。这是自我管理的一种方式,保证一个对象是完整独立的黑盒,自我运行,然后给出对应的结论。外部不得依赖、也不应依赖使用的某对象的状态。在使用对象时,只能通过消息给对象,让对象处理这个消息,自我运行,然后反馈结果,仅此而已。在代码编写中,如果状态共享(内部状态,可由外部管理或改变),则会造成很多不确定,在整个程序运行周期中,状态共享,意味着数据可在任意时刻,任意改变,而不仅仅只有对象可改变它。
在 Ruby 中,不会公开任何内部状态,而只能通过方法来改变对象的内部状态。
在面向对象语言中,有个非常重要的概念,往往会被忽略,即,消息传递。object.method(params)
这是众所周知的面向对象的函数调用方式,但往往不会将其和消息传递
挂钩,特别在 C++中,通常被称为函数调用。更准确的说法,是给object发送method消息,消息内容为params
或通知object处理method消息,消息内容为params
。所以正确的原型写法应为object.message(params)
。其他的写法在不同语言中语法有所不同,但都类似:Lua => object:method(para), Tcl => object method para , OCaml => object#method para, smalltalk => object method:para, OC => [object method:para], PHP => object->method(para),Haskell => method object para, Ada => method(object para)
如果以消息传递来理解面向对象,继承和多态就都不难理解。当继承时,派生类是需要扩展基类的消息处理集合,响应更丰富的消息类型。