![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=1738910998-w8ea4lih6fczz3Um3nocntKWQM55kJOm-0-f678329d5c72bb9aa1d321fdc8436bfe)
扫码看视频
我们先来看一段代码,如代码4.1所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_2.jpg?sign=1738910998-Spzh7zCMT9Vx4sMskljlUHPkDocJqni0-0-fc7cd1e8f96fa7353722fe2f1388755a)
这段代码很简单,定义了一个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=1738910998-QeZ2wIFbjND9RmhzG8bkGrQ5T3g1O7rC-0-298475d14abf855a167499c46e264326)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_4.jpg?sign=1738910998-3WahnKhic9O9ZULcGgibUm0WQLWz6CAl-0-0ba38b52a724eba7cfc70b4e0a132df1)
从代码中可以看到,Fish类除了使用extends关键字从Animal类继承,没有编写任何方法,但是在构造完Fish类的对象fh后,可以调用eat、sleep和breathe这三个方法,这就是继承的魅力,Fish类继承了Animal类的方法。
程序运行的结果为:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_5.jpg?sign=1738910998-pKyqpph09tKA6PxTsxODgIJnlSlOgqrm-0-5b3fbf4399f3afd858f794eda55742f7)
此外,还需要提醒读者的是,在第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=1738910998-p76reUJEFeimXWtKeTUURXByOlrKHlMz-0-e4a0e3688900d19f6d2981acbf84eb2f)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_7.jpg?sign=1738910998-qRJJR0E8u2XYeyCJS4aPgz532NUgDRM4-0-21ba99afd87416d04e1f2269b054435b)
程序运行的结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_8.jpg?sign=1738910998-TPIVjctHDTyCTJgizBM6sMcdcJ2SbKoJ-0-3b3fb2ffe957042072e6f8a1159e122b)
当构造子类对象时,父类对象会不会同时被构造呢?下面我们给Animal类和Fish类分别添加一个构造方法,在构造方法中输出一些信息,以便确认在子类对象构造时,它们是否会被调用,以及调用的先后顺序,如代码4.4所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_9.jpg?sign=1738910998-ksY7PjzmZ87mOvAVbRBExsZsBzpwOpeM-0-99f31c41d3e0676ea95cc540d6392258)
在main方法中,我们只构造了一个子类Fish的对象。编译并运行程序,结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_10.jpg?sign=1738910998-pr9Fc99jWJHkkxE1zSa5lGkbJiLH6LFi-0-21438222e2a1a1da91184f270118e23d)
可以看到,虽然代码中只是构造了一个子类对象,但父类Animal的构造方法也被调用了,而且是先调用的。其实这也很好理解,没有父亲哪里来的孩子呢?
好了,可以先将两个类的构造方法注释起来,准备后面内容的学习。