浅谈Java程序设计中继承的利与弊

 摘要:在 Java 中,正确应用继承,能够达到代码重用、增强可靠性、简化程序设计、提高编程效率、并使之易于维护的目的。但是一个程序中过多地使用继承是不可取的,它会带来一些局限性。本文就继承的利与弊进行一个分析。

  关键词:继承;超类;子类;代码重用

  继承在 Java 面向对象编程中是与生俱来的。所有类,无论是API,还是编程人员自己编写的,都自动继承于 Java 所有类的始祖——Object 类,代表了所有类的共性。

一、继承的概述

  继承是面向对象设计的特点之一。和现实世界中的继承概念一样,继承就是代码重用。通过继承并扩充已经存在或编好的类。例如API类,解决应用程序中的具体问题。继承在编程中是指两个或者多个类之间存在的特定关系——定义、功能,以及逻辑上的内在联系。称继承的基础、涵盖子类的类为超类,从超类导出或继承而来的类称为子类。

二、继承的好处

  正确应用继承技术,能够达到代码重用、增强可靠性、简化程序设计、提高编程效率、并使之易于维护的目的。

  1.代码重用

  代码重用性是指在存在继承关系的类中,超类已经存在的代码,包括成员变量和方法,可以继承到子类中。子类通过继承获得了这些代码,就可以像自己的“财产”或属性一样使用。不仅如此,子类还可以增添新的变量和方法,并且可以通过覆盖超类的方法改变自己的行为,使之功能更强大,解决的问题更具体。在继承中,一个子类可以有一个或者多级超类,形成一个继承链。紧挨着子类上面的超类被称作直接超类,或者父类;反过来讲,紧接着超类的子类被称作直接子类。沿着这个继承链再往上走,所有这些类都是子类的超类,或称间接超类,或者祖类。当然,最上面是所有类的始祖——Object。在继承中,一个子类继承了所有在该继承链上的父类和祖类的变量和方法,再加上自己新增的变量和方法。子类在继承中是相对而言的术语。一个子类很可能是下一级继承的超类。在继承链中从上往下,是一个从抽象到具体、从共性到特性的过程。超类代表所有其子类共有的变量和方法;子类继承这些属性,并可能增添代表它自己特征的变量和方法。这样保证了继承的效率,提高了代码的重用性。

  2.代码可靠性

  代码重用这一特点实际上蕴含着不可多得的益处——提高代码的可靠性。充分利用 API 类可以提高代码的可靠性,这些 API 类由职业语言开发者编写、经过多年的修改、改进和完善,经过广泛的不同规模和层次的实际应用,代码的可靠性应该毋庸置疑。在继承中利用 API 类,就如同“站在巨人的肩膀上”一样,除了代码重用之外,还大大提高了应用软件的可靠性。

    3.其他好处

  • 简化程序设计——继承API类的好处不言而喻。例如,编写一个有按钮、菜单、鼠标控制的窗口绘图软件,如果不继承 JDK 提供的 JFrame、JMenu、Graphics 等 API类,其编程难度可想而知。
  • 提高编程效率——简化程序设计必然会提高效率。如上例,我们不再为如何编写显示窗口的 JFrame 代码而伤透脑筋;也不必为如何控制鼠标的移动(MouseMoveListener) 而煞费苦心。
  • 增强程序维护性——继承体现面向对象编程的本质:模块化设计和封装性。对程序的更新改进,只涉及到相关的类,而不是整个程序体。正确运用继承,对代码的修改不会产生“触一发而动全身”的效应。封装性的功能使得能够做到不用了解具体代码详情就可使用的效果,大大简化和缩小了维修目标和纠错范围。例如,我们将会对程序的维护集中在继承而来的子类上,而不是作为超类的 API 类。

三、继承的局限

  使用继承最大的好处是可以实现代码的重利。但是,一个程序中过多地使用继承也是不可取的,因为它可能会为子类的改变带来困难。

  1.过多层次的继承带来的问题

  在软件工程理论中,一个软件产品要做到高内聚、低耦合。所谓内聚指的是模块内元素之间彼此关联的紧密程度,可以理解为软件中类内部之间的关联程度。所谓耦合指的是软件中几个不同的模块之间彼此关联的程度,可以理解为类与类之间相互依赖的程度。一个软件产品的高内聚、低耦合可以这样理解:这个软件产品中的每个类,都可以独立地完成某个特定的功能,并且类与类之间没有过多的依赖关系。过多层次的继承带来的一个问题就是会使软件产品的耦合性增强。

  过多层次的继承增强了类与类之间的依赖关系。最明显的问题是对顶层超类的改动可能会使与其相关的所有子类出现不正确的操作。如果继承的层次过多,而且对超类的更改过于频繁,会给底层子类的修改带来很多麻烦和问题。尤其是在一个大型的应用程序中,往往每一个软件开发人员只完成自己对应的模块,如果由于继承层次过多,使得对父类的修改造成其子类及相关的类的功能出现问题,那么修改起来所费的人力和工作量可能会是相当大的。

  2.其他局限

  1. Java 只支持单继承,而不允许多重继承,但可以利用接口实现多重继承。
  2. 对象一旦实例化,不能够转换角色。例如,学生对象不可能再转换成教师。
  3. 数据安全问题。例如,某个对象需要访问继承而来的超类数据,必须给予所有对象访问这些数据的访问权。
  4. 在多线程并行处理中,继承中的子类对象可能导致线程间的不协调问题。

  这些局限无疑对程序设计和编码提出了更高的要求。

  结束语

  继承给软件开发展示了无限机遇,也伴随着困惑和挑战,在 Java 程序设计中,要利用好继承这把“双刃剑”。

你可能感兴趣的:(JavaScript,OO)