![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=1734459739-iHmGwMhL21FQ3kcqHFHbB4jFvhBW4PBI-0-06b4e76eb5ea70873a9e6cd4316a35c5)
扫码看视频
我们先来看一段代码,如代码4.1所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_2.jpg?sign=1734459739-54pYHmsH7pQbwvPJkvNGdbns8PSIqnIm-0-86b461cf110038bac3fe7e2335ef66a8)
这段代码很简单,定义了一个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=1734459739-sHHBE4gV3aeDbXiXLaQWJN0FjwcqR9xj-0-e4b8142c27d35016e1bacf0a4037d84b)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_4.jpg?sign=1734459739-Tfp0QVmkJpPwJTZ0LlAYAQQMNCHzfFKN-0-03be99bf82ed88dd0db00f175c023e1d)
从代码中可以看到,Fish类除了使用extends关键字从Animal类继承,没有编写任何方法,但是在构造完Fish类的对象fh后,可以调用eat、sleep和breathe这三个方法,这就是继承的魅力,Fish类继承了Animal类的方法。
程序运行的结果为:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_5.jpg?sign=1734459739-irZEedRU3gROuRfMu2KecoC186mCU76z-0-48c87ea5d591a05144a9e89f59a5928e)
此外,还需要提醒读者的是,在第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=1734459739-SQM0Ov0SIdXHuKEWIeGgonaa3I76HXEz-0-6a34b270810aa94398a0b72a4581509f)
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_7.jpg?sign=1734459739-yycWS4ZSMEeAG7Ta6PNAPdLiSYy96oiB-0-070ac9a15efc8f2e809e465ba7883d36)
程序运行的结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_8.jpg?sign=1734459739-4pnmy6ZAu5b8Q3UXrln1SUuVpbBVrjb5-0-7d56648bc1110c55621130c3b7ffbfff)
当构造子类对象时,父类对象会不会同时被构造呢?下面我们给Animal类和Fish类分别添加一个构造方法,在构造方法中输出一些信息,以便确认在子类对象构造时,它们是否会被调用,以及调用的先后顺序,如代码4.4所示。
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_9.jpg?sign=1734459739-MfNa1gqHJls5gVBXmidaVbu3o23oAJoT-0-d51b449dfb7ac334524566acafada258)
在main方法中,我们只构造了一个子类Fish的对象。编译并运行程序,结果是:
![img](https://epubservercos.yuewen.com/AD1899/18685354708165706/epubprivate/OEBPS/Images/txt004_10.jpg?sign=1734459739-ycX3efQM0pMV960upUKqPYNSMTl0365s-0-37db0edcde44f9a703377225af169888)
可以看到,虽然代码中只是构造了一个子类对象,但父类Animal的构造方法也被调用了,而且是先调用的。其实这也很好理解,没有父亲哪里来的孩子呢?
好了,可以先将两个类的构造方法注释起来,准备后面内容的学习。