![Java无难事:详解Java编程核心思想与技术](https://wfqqreader-1252317822.image.myqcloud.com/cover/59/35011059/b_35011059.jpg)
4.1 继承
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_1.jpg?sign=1739566545-eM9EDrd80vO1lX9uGxI0XVTFwV7uMR0g-0-338f86885f46f3d26dd2a77c091c7147)
扫码看视频
我们先来看一段代码,如代码4.1所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_2.jpg?sign=1739566545-SAuiqzK5tGbDAjV2itt2ovRg4nRNIPRn-0-1a66634a0978e35292587646d4f4f362)
这段代码很简单,定义了一个Animal类,对于一个动物来说,它具有吃、睡觉、呼吸等行为,为此,我们在Animal类中分别定义了eat、sleep和breathe方法。
之后,我们想编写一个Fish类,代表鱼的抽象,鱼也具有吃、睡觉和呼吸的行为,那么在定义Fish类时,要再编写一遍eat、sleep和breathe方法,显得很烦琐!
鱼也是一种动物,在面向对象的程序设计中,对于同一归属的类,可以采用继承的方式来重用代码。继承可以让一个类拥有另外一个类的方法和成员变量,理解继承是理解面向对象程序设计的关键。
在Java中,通过关键字extends继承一个已有的类,被继承的类称为父类(超类、基类),新的类称为子类(派生类)。我们看代码4.2。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_3.jpg?sign=1739566545-6GNcyBB1mwmEZrDXiddMBoITfnnB7EFt-0-020d17afee7338caa23c17adfcb82964)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_4.jpg?sign=1739566545-ASKX4iIUz8HHsQeCyJpqbaxAOWHqSiZk-0-2a89c8c10e743de777c1a167328b68f7)
从代码中可以看到,Fish类除了使用extends关键字从Animal类继承,没有编写任何方法,但是在构造完Fish类的对象fh后,可以调用eat、sleep和breathe这三个方法,这就是继承的魅力,Fish类继承了Animal类的方法。
程序运行的结果为:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_5.jpg?sign=1739566545-QRmf1EUp2CvuMw26Kluz4BQw06pWtDw3-0-7b4a5037a94a0620e4d5a26d10b9f1c9)
此外,还需要提醒读者的是,在第1.7.2节中我们已经介绍过:
(1)在一个Java源文件中只能存在一个public类。
(2)在执行Java程序时,执行的类是main方法所在的类,针对本例,java.exe执行的是Fish类。
(3)与C++不同,在Java中,不允许多继承。
子类除了拥有继承自父类的方法外,还可以有自己的方法。比如鱼可以在水里游动,因此我们可以给Fish类再定义一个swim方法,如代码4.3所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_6.jpg?sign=1739566545-8y4F2ZYnfwxvsbeBhgdh1BTc31KrfKg5-0-2810b99558da7cc71f017a0ff5f08409)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_7.jpg?sign=1739566545-RJkHmmXfcBUwrNd7Qs0MXBg8JUszAdEF-0-7a308dfc5f7de6a1dbe91eee598ecb86)
程序运行的结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_8.jpg?sign=1739566545-ohcXpvGzt2V3vPQcjUxTGXPeUqxon5Ar-0-e19516bc604795835d453b253e9017af)
当构造子类对象时,父类对象会不会同时被构造呢?下面我们给Animal类和Fish类分别添加一个构造方法,在构造方法中输出一些信息,以便确认在子类对象构造时,它们是否会被调用,以及调用的先后顺序,如代码4.4所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_9.jpg?sign=1739566545-EconPjb188jdSGKdn874oohhMahGglPR-0-857d8660daa29c04ba1e0b6f29d7d786)
在main方法中,我们只构造了一个子类Fish的对象。编译并运行程序,结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_10.jpg?sign=1739566545-FbuWp7qLRpu208jL8dLLpaydHEZX15Mo-0-e5d2e11d81254e86042b7c7460c4167e)
可以看到,虽然代码中只是构造了一个子类对象,但父类Animal的构造方法也被调用了,而且是先调用的。其实这也很好理解,没有父亲哪里来的孩子呢?
好了,可以先将两个类的构造方法注释起来,准备后面内容的学习。