
4.1 继承

扫码看视频
我们先来看一段代码,如代码4.1所示。

这段代码很简单,定义了一个Animal类,对于一个动物来说,它具有吃、睡觉、呼吸等行为,为此,我们在Animal类中分别定义了eat、sleep和breathe方法。
之后,我们想编写一个Fish类,代表鱼的抽象,鱼也具有吃、睡觉和呼吸的行为,那么在定义Fish类时,要再编写一遍eat、sleep和breathe方法,显得很烦琐!
鱼也是一种动物,在面向对象的程序设计中,对于同一归属的类,可以采用继承的方式来重用代码。继承可以让一个类拥有另外一个类的方法和成员变量,理解继承是理解面向对象程序设计的关键。
在Java中,通过关键字extends继承一个已有的类,被继承的类称为父类(超类、基类),新的类称为子类(派生类)。我们看代码4.2。


从代码中可以看到,Fish类除了使用extends关键字从Animal类继承,没有编写任何方法,但是在构造完Fish类的对象fh后,可以调用eat、sleep和breathe这三个方法,这就是继承的魅力,Fish类继承了Animal类的方法。
程序运行的结果为:

此外,还需要提醒读者的是,在第1.7.2节中我们已经介绍过:
(1)在一个Java源文件中只能存在一个public类。
(2)在执行Java程序时,执行的类是main方法所在的类,针对本例,java.exe执行的是Fish类。
(3)与C++不同,在Java中,不允许多继承。
子类除了拥有继承自父类的方法外,还可以有自己的方法。比如鱼可以在水里游动,因此我们可以给Fish类再定义一个swim方法,如代码4.3所示。


程序运行的结果是:

当构造子类对象时,父类对象会不会同时被构造呢?下面我们给Animal类和Fish类分别添加一个构造方法,在构造方法中输出一些信息,以便确认在子类对象构造时,它们是否会被调用,以及调用的先后顺序,如代码4.4所示。

在main方法中,我们只构造了一个子类Fish的对象。编译并运行程序,结果是:

可以看到,虽然代码中只是构造了一个子类对象,但父类Animal的构造方法也被调用了,而且是先调用的。其实这也很好理解,没有父亲哪里来的孩子呢?
好了,可以先将两个类的构造方法注释起来,准备后面内容的学习。