继承
继承实现了高度复用的同时,也带来了一个严重的问题,破坏了父类的封装性。封装就是每个类应该把内容部信息(属性)和实现细节(方法)隐藏,值暴露必要的方法给其他类使用。但在继承中,子类可以更改父类的属性和方法,从而造成了子类和父类的高度耦合。
为了包装父类的良好的封装性,不会被子类随意更改。设计父类时应该遵循一下几个原则:
1,尽量把父类内部的数据隐藏,把属性设置成private,不让子类之间访问父类属性。
2,不要让子类随意覆盖父类的方法,像父类中哪些辅助其它方法的工具方法应该用private访问修饰符修饰。如果类中的方法需要被外部类调用,而不想被子类覆盖,可以使用final修饰。如果类中的方法只想被子类覆盖,而不像被其它类调用,可以使用protected来修饰该方法。
3,不要在父类的构造器中调用被子类重写的方法。
那么到底合适需要从父类派生子类呢?不仅需要子类是一种特殊的父类,而且还需要具备两个条件:
1,子类需要增加额外属性,而不仅仅是属性值的改变。
2,子类需要增加自己独有的行为方法。包括覆盖父类的方法和增加新方法。
组合
如果需要复用一个类,不仅可以使用继承,还可以使用组合。组合就是把需要复用的类最为新类的属性嵌入新类中。不管是继承还是组合,都允许在新类(对于继承来说就是子类)中调用复用类的public方法。组合时,通常在新类中用private修饰复用类。
到底该用继承?还是组合呢?继承表达的一种“是(is-a)”的关系。而组合表达的是一种“有(has-a)”的关系。继承是对已有类做的一番改造,让一个类是另一个类的特殊类型(子类是一种特殊的父类)。比如,狗 继承 了动物类,狗是一种动物(is-a),如果我用动物类去组合成够类并不合适。反之,如果两个类之间有整体和部分之间的关系,比如: 有一个arm(手臂)类,去组合成一个person(人类),arm是部分,person是一个整体,体现了has-a的关系。