简要介绍面向对象编程的 4 个原则:
private vs public
有些东西是别人能看到的,有些是只有自己知道的。
private 的东西自己负责管理,public 的东西可以被别人使用和改变。
object 之间只能通过 public methods 来沟通。
比如:一个人的思想是 private 的,但 TA 说的话是 public 的,别人可以通过和这个人说话来交互,但是不能直接看到这个人脑子里在想什么。
In object-oriented terms, we say that the public members encapsulate the private members of the class.
object 需要把复杂的细节藏起来,只提供别人需要的,而不是全部。
抽象的目的就是让我们可以方便的让别人做一些事情,不需要关心这件事到底是怎么完成的。
比如:
因为有了抽象这个概念,我们可以在不影响别人的情况下去修改具体的实现过程,只要最终能达到一样的结果就行了。
比如:
因为当 object 数量越来越多之后,假如每个 object 要关心一大堆跟它无关的事情,就没法集中精力管好自己的事情。
别忘了,程序是人写的,也是需要人去读懂去维护的,假如一个人需要考虑的事情太多了,千条万缕反而会抓不住重点,随着项目规模的扩大,出错的概率也就越大。
程序员们发现让每个 object 各司其职能减少脱发,这也跟我们之前说的 SOLID principle 里面的单一责任有异曲同工之妙(OOP 的项目天生具有 Single Responsibility 的属性呀~)。
人们又发现,当两个 object 非常相似(但不完全一样)的时候,假如能够有个继承的概念,就可以减少一大堆的工作量和重复代码。
于是就有了 parent - child 这一对概念,也被称为 base class - subtype class。
child 继承了 parent 的特性,也有自己独特的属性,继承是单向的(也就是 parent 不能继承 child)。
比如:
继承的好处就在于我们可以重复使用 parent 的属性,建立不同 class 之间的一种父子关系。
当 parent 和 child 对于同一个问题有不同的解决方案时,听谁的?
首先,child 有着 parent 所有的属性(还记得吗?SOLID 里面讲到的 Liskov Substitution Principle 里氏替换原则,就是说 child 可以替换 parent);
其次,在程序运行的过程中,一个 object 可能是被当成 parent 来用的,也可能是被当成 child 来用的,到底是哪个,运行的时候才知道;
比如我们有个 school list,里面有不同的学校类型,由于子类可以替换父类,所以可以用父类来代表 list 里面所有的学校:
|
|
School, PublicSchool, PrivateSchool 都有一个 GetEnrollmentFee()
的方法,各自返回不同的结果,子类方法 override 父类方法。
在运行的时候,即使这两个 object 是 School(父类)类型,也会调用子类(PublicSchool、PrivateSchool)里面的方法,因为程序运行时它事实上就是一个子类。
反之,假如子类没有 override 父类方法,那么在运行时会继续使用父类方法。
|
|
简而言之,多态就是指程序在运行中可以判断 object 类型并且根据 runtime object type 来调用方法。