“1.4 被隐藏的具体实现”这一小节讲到了一个访问控制权限的问题,讨论这个问题之前,首先将类,也就是我们的抽象按照角色划分为类创建者和类使用者。类的创建者向类使用者暴露哪些部分,隐藏哪些部分,这是很重要的事情。
一个类的被隐藏的部分为什么要被隐藏?如果需要被隐藏起来而没有隐藏起来会造成什么影响?这其实是程序或者我们系统健壮性的问题。
我认为一个类被隐藏的部分被隐藏起来的原因主要有两个,一个是该部分不该让使用者看到,对他们来讲没有意义或者没有直接目的;第二个就是该被隐藏的部分如果没有被隐藏,被使用者使用了会造成这个类的重大破坏,甚至引起重大的bug。当然类的创建者在修改这部分被隐藏的部分时也要格外的小心,要充分考虑类的使用者使用到的没有被隐藏的部分。
下面介绍了Java编程语言使用到三个关键字在类的内部设定边界:public、private、protected还有一种默认的访问权限即没有上面三个关键字的。这一块可以先通过简单了解一下,后面还会详细介绍。
(1)public:可以被所有其他类所访问。
(2)private:只能被自己访问和修改。
(3)protected:自身,子类及同一个包中类可以访问。
(4)default(默认):同一包中的类可以访问,声明时没有加修饰符。
下面就到了”1.5 复用具体实现”这一小节了,这一节讲的是代码复用问题。要让一个类的代码在任何通用的场合都能不做任何修改的情况下被使用是一件了不起的事情。当然通过不断的迭代使其达到这种效果也是了不起的事情。
书中举了一个汽车和引擎的关系的例子同时引入了组合的概念来说明复用的问题。这里面同时还引出了继承,也就是”1.6 继承”这一小节要将的内容。组合常被视为”has-a”拥有的关系,继承被视为”is-a”是一个的关系。比如汽车拥有一个引擎,那么汽车和引擎的关系就是组合,引擎作为汽车的一部分,具有高度的复用性,而且驾驶员是操作汽车,不会去操作引擎的,这一点说明引擎在汽车里属于私有的。而”1.6 继承”这一小节给出的继承的例子也是比较常见的图形的关系。
圆形、方形和三角形都是一种几何形,这一点说明是继承的关系,不能是组合的关系,不能说图形拥有圆形,这一点从语义上说不通。继承关系的话,就像上面UML图表示的那样,Circle继承下来的draw方法和其他两个Square、Triangle继承下来的draw方法的实现肯定都是互相不一样的,从形状的数学几何表示上就可以看出来。在继承关系中Shape称为基类或超类或父类,Circle、Square、Triangle称为导出类或继承类或子类。这些概念可以先记住,都是一样的,想要根深蒂固需要不断的写代码实践才行。
上面说到了Circle、Square、Triangle继承了Shape中的draw方法的实现肯定都是互相不一样的,这就是子类对基类的方法行为的覆盖。当然子类中还会有自己的新的方法,也可以选择不使用基类中的方法,这点说明基类对子类是不可控的,子类有更大的灵活性去做自己的事情。这又引出了该小节中的另一个问题,就是”是一个”与”像是一个”关系的问题。简单的理解吧,如果Circle从Shape继承下来的所有属性和行为都满足自己的需求而不添加新的元素(属性和方法),那么就说Circle是一个Shape,是is-a的关系。用文中另一个例子说明”像是一个”的关系。
Air Conditioner空调是一种Cooling System制冷系统,Heat Pump热力泵也是一种制冷系统,这个热力泵就is-like-a空调。这里面的”像是一个”的关系不是子类和基类的关系,而是子类之间有一种像的关系。当然就像书中说的,制冷系统这个基类不够一般化,所以才会有”is-like-a”这种关系。制冷系统代替不了热力泵,因为制冷系统不包含制热功能。就不能套用替代原则,这里的替代原则就是面向对象7大原则里的里氏替换原则,先记住,以后再回味这一个点。