每个特性存在的意义和目的,以及要解决哪些编程问题。
一、封装 Encapsulation
封装也叫数据隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(函数)来访问内部信息或者数据。
封装需要编程语言本身提供访问权限控制语法机制,来达成隐藏信息和保护数据的目的。
意义:
可控性: 如果对类中属性的访问不做限制,那任何代码都可以访问、修改类中的属性。
易用性: 类仅仅通过有限的方法暴露必要的操作,可以提高类的易用性。只暴露少许几个必要的方法,调用者用错的概率就减少很多。
二、抽象 Abstraction
抽象是指隐藏方法的具体实现,调用者只需要关心方法提供了哪些功能,并不需要知道这些功能是如何实现的。
通过函数包裹具体的实现逻辑,这本身也是抽象。即通过函数的命名、注释、文档来了解其提供了什么功能,而不需要去研究函数内部的实现逻辑。
在面向对象编程中,我们常使用编程语言提供的接口类或抽象类这两种语法机制来实现抽象特性。
抽象是一个非常通用的设计思想,不单单用在面向对象编程中,也可以用来指导架构设计。因为只需要提供函数这一基本语法机制,就可以实现抽象特性,没有很强的特异性,所以它有时候不被看作面向对象编程的特性之一。
意义:
降低复杂性: 调用者只需关注功能点不需关注实现,帮助过滤非必要的信息。
指导了代码设计: 很多设计原则都体现了抽象设计思想,如解耦、开闭、基于接口而非实现
三、继承 Inheritance
继承用来表示类之间的is-a关系,如汽车是交通工具、机械。包括单继承、多继承。
不过如果过度使用,会导致可读性、可维护性变差;另外子类和父类高度耦合,修改父类代码会直接影响子类。
意义:
代码复用: 多个子类重用父类中的代码,不过也可以用组合来解决这个问题。
易读: 反应真实世界中的关系,符合人类的认知
四、多态 Polymorphism
子类替换父类,即父类引用指向子类对象,在实际的代码运行过程中,调用子类的方法实现。
多态也需要编程语言提供特殊的语法机制来实现:
1、要支持父类对象可以引用子类对象。
2、要支持继承或实现接口类。
3、要支持子类可以重写(override)父类的方法。
动态语言特有的的duck-typing:只要两个类具有相同的方法,就可以实现多态,并不需要两个类之间有任何关系。
意义:
可扩展性、复用性
是很多设计模式、设计原则、编程技巧的代码实现基础: 比如策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、利用多态去掉冗长的 if-else 语句等等。