两个“不合理继承 ”的判定标识

继承作为面向对象编程中的一项重大特性,其有着独特的威力——代码复用、功能扩展、运行多态  这些都与继承有着密切的关系。

 

代码复用:

将一组平行类中的相同或相似功能提取到父类,利用继承父类、重用父类代码,可大大减少的代码量。

 

功能扩展:

如果某个类已经拥有了 ABC 功能,这时想添加一项功能D,但却不想或者不能修改该类,则可以新建子类、利用继承,获得ABC 功能,并在子类中添加 D功能,即可实现目标。

 

运行多态:

继承的关键字:C#冒号、Javaextends,其有两种形式的用法。

1)当作占位符去使用:【关于这一点仔细思考静态语言和动态语言的差异性就能理解了】

2)搭建继承体系

 

无论是以上的那种用法,其和面向对象编程的另一个特性——多态,它们之间的亲密度可以用“如胶似漆”去形容,在很多情况下继承中都会存在多态的“影子”。

 

以上三点可以作为继承的优点,但是有利必有弊:

1)子类将强制继承父类的全部非私有功能。

2)父类中任何修改都有可能会影响到全部子类。

3)如果继承体系过长,很容易造成代码冗余。

4)等等。

 

当然如果继承体系搭建的很合理、足以应对需求变化,

那从当前角度出发考虑问题(PS:人没有足够强的预知能力),上述的缺点是可以忽略的。

 

但是往往继承体系搭建的并不合理,也就是通常意义上的滥用继承。

我想许多人在继承的使用方面都会经历以下的几个阶段:

1)不会使用继承

2)滥用继承,即遇到任何可以搭建继承体系的代码都会去使用继承【当然这个描述有点极端了】。

3)少用继承

4)使用组合代替继承

5)继承组合+ 封装完美协作

 

PS:

工厂方法模板方法继承的典型用法。

状态模式装饰者模式组合 + 封装极致体现。

 

本文标题为《两个“不合理继承”的判定标识》,现在进入正题,当然前面的铺垫在我看来是必不可少的,且正文篇幅也不是足够大:

 

如果满足如下的这个条件,即可判定为“不合理的继承”,背景条件,有如下代码

 

public class Base{

protected int id;

 

public int getId() {

return id;

}

}

 

public class A extends Base{

// 在此类中可以自由访问 id

}

 

现状:

Base类:封装了 Base类、或者说是封装了id ,使id的访问收到保护。

A类:扩展了Base 类,但是在 A 中可以自由访问 id

 

判定条件:如何A类中自由访问id是不合理的,则可以判定为不合理继承,即破坏了封装的继承是不合理的

往往破坏了封装的继承实际上使用组合更合理,往往破坏了封装的继承的两个类实际上是两个独立的职责,也就是违反了单一职责原则。

 

 

此判定方式是利用封装的特性去盘判定的,此外利用现实世界继承体系是否冲突也可以作为判定条件,案例如:

 

普通游戏玩家职业游戏玩家两个类,但是不应该建立一个“所有人都玩游戏”的父类,而可以建立一个“所有玩游戏的人”的父类。进而搭建继承体系。因为:不是所有人都玩游戏,这与“真实世界”相冲突了。

 

当然还有许多其他类型的不合理继承的,比如不能满足特殊业务需求等等,总之:继承没有对与错,而是合理与不合理,而是否合理最终的判定条件是要视情况而定,以上只是列举了两种简易的判别方式。

 

————————————————————————————————————————————————————————————

续写:2013-11-28

————————————————————————————————————————————————————————————

不合理继承的“危害”:

1)造成结构混乱,增加代码复杂度,加大学习成本、尤其是“新人”,同时给代码命名也带来一定困扰。

2)增加维护复杂度、无论是修改功能还是添加新功能,牵一发而动全身:在维护一项功能的时候,会牵扯出许多其他的功能,给测试带来不必要的麻烦。

 

 

 

 

 

 

 

posted @ 2013-11-27 13:23  把爱延续  阅读(275)  评论(0编辑  收藏  举报