Table of Contents
概述
面向对象的三大特特点是"封装、"多态"、"继承",很多人认为组合,也应该是其中一个重要的特点,这样的话就是四大特点。。面向对象的五大原则分别是是"单一职责原则"、"开放封闭原则"、"里氏替换原则"、"依赖倒置原则"、"接口分离原则"。
面向对象的特点
封装比较好理解,就是将属于一个抽象的方法属性特点等封装到一个类里面。
多态是我们比较熟悉的另一个重要技术,关于多态的详细介绍可以参考博客:[java] 反射和多态实现原理详解以及对比
继承
继承是一个需要谨慎选择的技术,原因在于继承是一种比较强的耦合关系。如何判断什么时候应该使用继承,只需要把握如下的规则:
到底是is a 还是has a? 所谓is a就是指的某一个抽象是否可以描述为是另一种抽象,例如,轿车是车,这就是is a的一个例子。而has a指的就是某个抽象不是某一种抽象但包含另一种抽象,例如,轮胎不是车,但车包含轮胎,这就是has a的一个例子。
值得指出的是,有的时候is a是不够的,例如Apple pen的例子,一个apple pen就是一直笔也是一个apple。这个时候就是多重继承的使用场景。
组合
我们可以通过一段代码来说明什么是组合:
public class Car {
INavigator navigator = null;
public void setNavigator(INavigator navigator ) {
this.navigator = navigator;
}
public void openNavigator() {
……
}
}
代码非常简单,就是汽车和汽车的导航的关系,导航很明显不是汽车,汽车很明显也不是导航,但是在汽车上使用导航却是一个非常常见的场景。
并且,在《effective java》一书中明确指出了组合优先于继承这样的一个设计原则。原因在于,组合的耦合度相对于继承来说实在是低太多了,但是通过组合你也能够任意的使用所有组合的类当中的方法。
在java的源代码中有一个经典的组合的例子,就是HashSet和HashMap的例子。感兴趣的读者可以自行查看HashSet的源代码。
关于面向对象的特性更深入的理解可以参考博客:难的问题到底难在哪儿
面向对象的五大原则
单一职责原则
单一职责原则,Single Responsibility Principle。它的定义是:就一个类而言,应该仅有一个引起它变化的原因。引起变化的原因描述的很抽象,我们也可以理解为一个类应该准确的描述一个东西,事物。例如汽车这个类只应该描述汽车的属性,轮胎的属性它不应该关系,轮胎的变化也不应该引起它的变化。
开放封闭原则
开闭原则,Open Close Principle,它是Java世界里最基础的设计原则,指导我们如何建立一个稳定的、灵活的系统。开闭原则的定义是:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是,对于修改是封闭的。例如接口,我们可以同过提供不同的接口实现扩展,但是对于已经写好的接口实现则不应轻易修改,在各大框架比如spring当中,这样的设计不胜枚举。
里氏替换原则
里氏替换原则,Liskov Substitution Principle。我们知道,面向对象的语言的三大特点是继承、封装、多态,里氏替换原则就是依赖于继承、多态这两大特性。里氏替换原则简单来说就是,所有引用父类的地方必须能透明地使用其子类的对象。通俗点讲,只要父类能出现的地方子类就可以出现。但是,反过来就不行了,有子类出现的地方,父类未必就能适应。
从技术层面来说,继承是多态的先决条件之一,关于多态的实现原理和介绍可以参考这篇博客:[java] 反射和多态实现原理详解以及对比。
依赖倒置原则
依赖倒置原则,Dependence Inversion Principle。依赖反转原则一种解耦的方式,是指程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程。这样的好处体现在代码当中事实上就是多态的好处。只是依赖倒置原则将多态的好处理论化了。
多态可以看作是dip原则的技术实现。而在现实世界当中,有的地方技术无法支持的。
依赖倒置的好处是非常多的,因为抽象往往是稳定的,而实现的具体实现细节则较不稳定,而我们往往又希望软件具有更好的稳定性,可见该原则非常重要。
接口分离原则
接口隔离原则,InterfaceSegregation Principle。它的定义是:客户端不应该依赖它不需要的接口。另一种定义是:类间的依赖关系应该建立在最小的接口上,最小这个词语又很模糊,再换个说法:在设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。因为这样各个接口之间的职责是更加清晰的,也是更加单一的。
上述五个原则的英文各取首字母,正好组成英文单词SOLID,因此我们也叫它们solid原则。这几个原则之间并不是相互独立的,各个原则之间有着密切的联系,甚至存在着相互解释的关系,例如对于接口分离原则来说,更加分散的接口必然是更加符合单一职责原则的。五大原则和面向对象三大特性之间也有着非常密切的联系。
除了solid之外面向对象里面还有一个原则也经常用到,那就是迪米特法则。
迪米特法则
迪米特法则也叫做最少知道原则,英文是Law of Demeter,它的意思是:一个对象应该对其他对象有最少的了解。通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,类的内部如何实现、如何复杂都与调用者或者依赖者没关系,调用者或者依赖者只需要知道他需要的方法即可,其他的我一概不关心。这一点其实与单一职责原则有重叠的地方。