![名师讲坛:Java开发实战经典(第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/824/26793824/b_26793824.jpg)
6.1 继承的基本概念
在讲解继承的基本概念之前,读者可以先想一想这样一个问题:现在假设有一个Person类,里面有name与age两个属性,而另外一个Student类,需要有name、age、school 3个属性,如图6-1所示,具体代码如下。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P160_124293.jpg?sign=1739890767-Mc26nnz7Ti2QFUm2tkTkI2Cwzoicryoj-0-f7e1924d0efdf01bcb3be9b428bbd0f6)
图6-1 Person和Student类
【例6.1】Person类
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P160_124296.jpg?sign=1739890767-xWZdhDCqFOLt9hlvLjHn3kDIt22LxPjE-0-784fd8b07f171711dac0b38f42fbf47a)
【例6.2】Student类
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124298.jpg?sign=1739890767-zWG8a2P9v5Xps04B3tlu3SD0njvWaLfQ-0-fb4359ff984cddb77fa71d2846800214)
从上面的代码中可以发现Person类中已经存在name和age两个属性,所以不希望在Student类中再重新声明这两个属性,这个时候就需要考虑是不是可以将Person类中的内容继续保留到Student类中,这也就是继承所要解决的问题。
在Java中如果要想实现继承,可以直接使用如下的语法来表示。
【格式6-1 类的继承格式】
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124299.jpg?sign=1739890767-BgfQufS5Ng1MxW4KEMUjtzRH3j2f3md3-0-c0d93fbe0841c361ee7e2ef8324b6a38)
下面依照以上的格式进行继承的操作,具体代码如下。
【例6.3】继承的实现
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124300.jpg?sign=1739890767-aLzgpQk1Fng6aeFyUhuiT0JsRYc0wLWn-0-bbaac2330c5ebcc0c683a7f427bae9ce)
程序执行结果:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P162_124302.jpg?sign=1739890767-VKeKc44TAt0Ku13Dcp2n9FFgZQ3mskYn-0-0240f84dba93a2581d8c926a71b1ad36)
从以上的程序中读者可以发现,在Student类中并没有定义任何的操作,但是通过继承的功能可以直接把父类中的操作直接拿到子类中使用。当然,子类也可以定义自己的属性或方法,如下面代码所示。
【例6.4】通过子类扩展父类的功能
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P162_124303.jpg?sign=1739890767-Kniry32ZhQ354x79knrDzHOmxD0iaZ8b-0-e91770359ddeb9709817df1b5270615f)
程序执行结果:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_124305.jpg?sign=1739890767-A4jOFhtQx5uyn210LAJVoMLG9ODzdvfF-0-6c95b6ff82501f49e1b4662f946deaf6)
以上的程序Student类扩充了Person,增加了学校的属性及对应的setter、getter方法。也就是说此时Student类中已经存在了3个属性及3组setter()、getter()方法,如图6-2所示。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_21556.jpg?sign=1739890767-AK5iwwc8gRyk0JoanaM7oUdHl7VyRHCl-0-4c0129584eadc3a23b41a654b964ab3c)
图6-2 Person与Student类的继承图
注意
只允许多层继承不能多重继承。
在Java中只允许单继承,不能使用多重继承,即:一个子类只能继承一个父类,如图6-3所示;允许进行多层继承,即:一个子类可以有一个父类,一个父类还可以有一个父类,如图6-4所示。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_21564.jpg?sign=1739890767-WdeSE9pbPleSvc5fHe9rDiSYTg1y4rTf-0-73f1e8154e0e8475e1d3073c8c82e018)
图6-3 多重继承
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_21565.jpg?sign=1739890767-Zh1ZxKlyigwiyU4KU7gsW7Kd8wbRvkS1-0-079220d74c7166e2605a4a05cd9aabfd)
图6-4 多层继承
实例1:错误的继承代码
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124310.jpg?sign=1739890767-hG47IvbSwmNG4Jip5Wy0somIPE3mjgjN-0-e5b791aad233f0369adff891b5bcff24)
由上面的代码可以发现类C同时继承了类A与类B,也就是说C类同时继承了两个父类,这是不允许的。
实例2:多层继承
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124312.jpg?sign=1739890767-EtGWkDEVD6KJyLdQU6Yg0XO9ITPLvxxt-0-c8dc6e16b08aee07ee63b978bdc5ea6f)
由上面可以发现类B继承了类A,而类C又继承了类B,也就是说类B是类A的子类,而类C则是类A的孙子类。
同样,在类图的表示中对于继承也是有明确的要求的,可以使用如下形式的图形表示类的继承关系。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_21575.jpg?sign=1739890767-5dOon4Z3lKGzESu6lxPjLPQmRhl9oAk0-0-8518e85eecac9b7810088554a790337a)
图6-5 继承的类图表示
提示
继承的子类有时也称为派生类。
使用extends关键字可以实现继承的关系,但是这个关键字的本身含义是“扩展”,更准确地说是一个类扩展已有类的功能,在其他的书中也会经常把子类称为派生类。
在使用继承的时候也应注意的是:子类是不能直接访问父类中的私有成员的,但是子类可以调用父类中的非私有方法,但是不能直接调用父类中的私有成员,如图6-6所示。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124315.jpg?sign=1739890767-ecrBs1uYjOfCzhh9qtUP0P5BYkhyzGMG-0-e08684380b83293f9ba8eeb9d6b137d1)
图6-6 子类访问的限制
【例6.5】子类访问限制
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124316.jpg?sign=1739890767-7dKQc54Nmew7Azhm3TgGcjakxyBoJF61-0-81d5202c6b81d83cd7cca3b5530bcf59)
编译时错误:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P165_124317.jpg?sign=1739890767-Jsrv5ixQeXgtJJZypV2RxF4bT0h56LN0-0-b034752a4b66b61a91ea5bb3d74140fd)
上面的代码中,子类直接访问了父类中的私有属性,所以在编译的时候编译器会通知用户name和age属性无法访问,如果此时不直接访问name()或age()属性,而是直接通过setter()或getter()方法调用的话,就可以访问。
【例6.6】通过getter方法间接取得属性内容
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P165_124318.jpg?sign=1739890767-nMZgpO1akKZFPWoefR70p8AhSlKOhAoX-0-72f6504123b20204f05c74d826795781)