Java编程思想第二周
- 内容导读:继承,类型转换
1.5 继承:重新使用接口
我们费尽心思做出一种数据类型后,假如不得不又新建一种类型,令其实现大致相同的功能,那会是一件非常令人灰心的事情。但若能利用现成的数据类型,对其进行“克隆”,再根据情况进行添加和修改,情况就显得理想多了。“继承”正是针对这个目标而设计的。但继承并不完全等价于克隆。在继承过程中,若原始类(正式名称叫作基础类、超类或父类)发生了变化,修改过的“克隆”类(正式名称叫作继承类或子类)也会反映出这种变化。在Java 语言中,继承是通过 extends关键字实现的使用继承时,相当于创建了一个新类。这个新类不仅包含了现有类型的所有成员(尽管private 成员被隐藏起来,且不能访问),但更重要的是,它复制了基础类的接口。也就是说,可向基础类的对象发送的所有消息亦可原样发给衍生类的对象。根据可以发送的消息,我们能知道类的类型。这意味着衍生类具有与基础类相同的类型!为真正理解面向对象程序设计的含义,首先必须认识到这种类型的等价关系。
- 首先,继承是为了复用代码而出现,但是又不是使用完全相同的代码,所以子类一般会有额外的修改,但是除此之外皆与父类系统。
- 这里的接口指的应该是方法,父类中存在的方法则在子类中一定存在,这样面对一个已知父类下的子类时,则可以使用与父类相同名称的方法来调用子类,而不用担心不存在这个接口。
由于基础类和衍生类具有相同的接口,所以那个接口必须进行特殊的设计。也就是说,对象接收到一条特定的消息后,必须有一个“方法”能够执行。若只是简单地继承一个类,并不做其他任何事情,来自基础类接口的方法就会直接照搬到衍生类。这意味着衍生类的对象不仅有相同的类型,也有同样的行为,这一后果通常是我们不愿见到的。
- 如果不重写子类的实现,则其功能与父类完全相同,这样子类的存在则没有什么意义。当然一个子类不一定会重写父类所有的方法,但是最起码会修改一个方法。
1.5.2 等价与类似关系
针对继承可能会产生这样的一个争论:继承只能改善原基础类的函数吗?若答案是肯定的,则衍生类型就是与基础类完全相同的类型,因为都拥有完全相同的接口。这样造成的结果就是:我们完全能够将衍生类的一个对象换成基础类的一个对象!可将其想象成一种“纯替换”。在某种意义上,这是进行继承的一种理想方式。此时,我们通常认为基础类和衍生类之间存在一种“等价”关系——因为我们可以理直气壮地说:“圆就是一种几何形状”。为了对继承进行测试,一个办法就是看看自己是否能把它们套入这种“等价”关系中,看看是否有意义。
但在许多时候,我们必须为衍生类型加入新的接口元素。所以不仅扩展了接口,也创建了一种新类型。这种新类型仍可替换成基础类型,但这种替换并不是完美的,因为不可在基础类里访问新函数。我们将其称作“类似”关系;新类型拥有旧类型的接口,但也包含了其他函数,所以不能说它们是完全等价的。
- 父类存在的地方则一定可以替换成子类来使用,这就是替换。但是父类可能是无法替换子类出现的地方,因为子类可能存在新建的接口,而这个接口是父类所不存在的,这是类似。
1.6 多形对象的互换使用
对这样的一系列类(形状类下有圆形正方形等子类),我们要进行的一项重要处理就是将衍生类的对象当作基础类的一个对象对待。这一点是非常重要的,因为它意味着我们只需编写单一的代码,令其忽略类型的特定细节,只与基础类打交道。这样一来,那些代码就可与类型信息分开。所以更易编写,也更易理解。此外,若通过继承增添了一种新类型,如“三角形”,那么我们为“几何形状”新类型编写的代码会象在旧类型里一样良好地工作。所以说程序具备了“扩展能力”,具有“扩展性”。
- 编写代码面向父类,面向抽象编写,这样在添加,修改,删除子类时,不会对代码造成巨大破坏。同时这样的代码具备扩展的能力,当需要新的功能时,新增一个子类即可,不会对原有的运行代码造成破坏。
一个 Circle(圆)句柄传递给一个本来期待 Shape(形状)句柄的函数。由于圆是一种几何形状,所
以doStuff()能正确地进行处理。也就是说,凡是 doStuff()能发给一个 Shape的消息,Circle也能接收。
所以这样做是安全的,不会造成错误。
我们将这种把衍生类型当作它的基本类型处理的过程叫作“Upcasting”(上溯造型)。其中,“cast”(造型)是指根据一个现成的模型创建;而“Up”(向上)表明继承的方向是从“上面”来的——即基础类位于顶部,而衍生类在下方展开。所以,根据基础类进行造型就是一个从上面继承的过程,即“Upcasting”。在面向对象的程序里,通常都要用到上溯造型技术。这是避免去调查准确类型的一个好办法。
- 把子类当作父类去使用接口的方式称为上溯造型,表示向继承的上方,也就是父类一样去cast自身后使用。这一行为在Java编码中非常的常用。
PS:这周换工作地点了,熟悉(懒)一周,所以就看了一天,从下个星期开始会继续更新的。
END
Java编程思想第二周