一、面向对象基本理论
1.1 类
一组相似事物的统称。关键字:一组(不是一个)、相似(不是相同)、统称(不是具体的“称”)。
类,代表了具有相似能力、相似属性的一类事物。
1.2 对象
对象,类的一个实体。如果说“类”是职责的承担者那么“对象”就是职责的执行者;类从程序世界的上帝(程序猴)那里获得了职责,对象则在程序世界里履行着这些职责。
1.3 接口
一组相关的交互功能点定义的集合。关键字:一组(不是一个)、相关(不是随意的)、交互(不是自娱自乐)、功能点定义(不是功能点实现)。
二、面向对象三大核心特征
2.1 封装
封装,将一些东西放在一起并且实现信息隐藏。放在一起的东西是因为它们有着相似之处,或者他们彼此需要在一起。
因为面向对象是一种符合或者比较贴近人的思维方式的程序设计理念,而人类社会又是一个分工的社会(分工合作才能实现效率的最大化嘛),所以面向对象也应该体现“分工”的程序设计理念,而这就体现在“类”的存在上,每一个“类”都有着自己的角色和本领——都要为系统(程序)的正常运行而做出自己的贡献。
对比人类社会,比如我希望厨师为我做一顿大餐,那么我只需要聘请一位厨师就好,我不需要知道厨师是如何购买原材料、如何进行烹饪,我只需知道他可以做出大餐即可。这就是现实版“封装”:隐藏了厨师做大餐的细节——将专业的事情交给专业的人去做!其实这就是方法(做大餐)的封装,厨师将做大餐的细节封装在自己的脑袋里,保证自己不会失业嘛。
再比如,我不想让别人知道我的具体收入情况(财不外露嘛),但是我自己还是需要一个账本的,那么我就要把这个账本放在安全的地方,于是我就把账本“封装”到别人无法直接接触到的地方(保险柜?银行?沙发、床底?),当然经过我的允许之后还是可以查看它的内容的~。
其实,封装包括方法封装和数据封装。
方法封装的目的是“隔离复杂度”——将专业的事情交给专业的人!如果我不是厨师,而我又想自己做大餐(其实我不会这么想的),最后可能只有我一个人觉得它是大餐了;
数据封装的目的是“信息隐藏”——每个类都有自己的小秘密嘛,不想别人知道,所以就“封装”起来。
而,封装的核心目的是:拥抱变化。唯一不变的只有变化本身。通过封装,将变化所带来的影响控制到最小,比如,厨师因为“变化”get了另一种大餐的做法,它和原来大餐的做法完全不同。正因为 “做大餐”作为一种方法被封装在厨师内部,所以这一变化基本上没有影响到吃大餐的人的行为(我只负责吃):新增的大餐(新增的变化)只影响到厨师,而不影响到我。事实上,通过良好的设计,可以把get大餐的新做法这一变化对厨师的影响也降到最小。
2.2 继承
继承描述了类和类之间的关系,实际上也是对现实世界物与物之间关系的一种描述,比如:子承父业。子类通过继承,得到了父类的所有属性和方法,没错,是所有,使得子类可以在父类的基础上进行新的扩展和改进。
再来谈谈为继承而生的类——抽象类。
抽象类是为继承而存在的类,它本身无法生产对象,但是它定义了子类必须实现的功能。如果说我们通过“抽象”从相似事物中得到了类,那么我们再一次通过“抽象”从类中得到了抽象类。抽象类更多的是定义了子类必须遵守的一种规范——你要继承我,就必须实现我对你的要求,除非你也抽象类。
其实个人认为,继承的目的大多在于对父类的功能进行改进(可能限于经验,看法有些短浅*_*)。
2.3 多态
多态:多种形态。在面向对象的程序中,可以以多种形态存在的事物有哪些呢?类和方法。父类可以被多个子类继承,这些子类就是父类的多种形态,这是通过继承实现的多态;方法通过不同的形参获得多种形态,这是通过函数的重载实现的多态;其实,通过子类继承父类后重写父类的方法是实现面向对象程序设计语言动态方法调度(当通过父类引用调用子类对象的重写方法时根据子类对象的类型判断调用哪一版本的方法)也就是实现运行时多态的重要方法。
文章中的定义部分来自:《面向对象葵花宝典 : 思想、技巧与实践 / 李运华编著》,很棒的一本书~