![名师讲坛: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=1739283045-z7vtRNqbthTYl2cVHGPuoYXov25bw65b-0-63b1f667087ba914034f1a88067e0ec4)
图6-1 Person和Student类
【例6.1】Person类
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P160_124296.jpg?sign=1739283045-rkgrsLrhlA1kZ1kx4LpE0qC6B2EZqnbc-0-12ac83f75fe11b2bae77226c66eb13f7)
【例6.2】Student类
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124298.jpg?sign=1739283045-EC9ibPfnMvIsHB8OxebdSuszAlGR68rv-0-36d558d50d4542286934b0143c431371)
从上面的代码中可以发现Person类中已经存在name和age两个属性,所以不希望在Student类中再重新声明这两个属性,这个时候就需要考虑是不是可以将Person类中的内容继续保留到Student类中,这也就是继承所要解决的问题。
在Java中如果要想实现继承,可以直接使用如下的语法来表示。
【格式6-1 类的继承格式】
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124299.jpg?sign=1739283045-8d3T8Vdvpjf3JXN0Pau9C1lVEKlHhV9Q-0-b5f87678b635e2bf527f9ea3fb948f95)
下面依照以上的格式进行继承的操作,具体代码如下。
【例6.3】继承的实现
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P161_124300.jpg?sign=1739283045-9vK5KLgoJwIbS00w97BRfD6UYbvxxzFF-0-75d0fb1de2abf4f2de9934121c095630)
程序执行结果:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P162_124302.jpg?sign=1739283045-LSoxZ2Uucmkt8hWoaidzF5FiXW9E4f6l-0-b2ee6dc7255bcf16079960fd5429ac22)
从以上的程序中读者可以发现,在Student类中并没有定义任何的操作,但是通过继承的功能可以直接把父类中的操作直接拿到子类中使用。当然,子类也可以定义自己的属性或方法,如下面代码所示。
【例6.4】通过子类扩展父类的功能
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P162_124303.jpg?sign=1739283045-xc68oMlZUD7kA4q6SgrTHtO5tb8GtQ5t-0-7aef49b5253a32b5ab1684ccd93f94c2)
程序执行结果:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_124305.jpg?sign=1739283045-afyht1Z2VBBBZnK4x8f92s6XliEQZ6Sx-0-41a261d10c7480ea98c588d1038d02d2)
以上的程序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=1739283045-qbdCh299SGGIi6tyLJjKj58UveiZFvZX-0-799b3c05f3dffaa062c8a56c8f5bb111)
图6-2 Person与Student类的继承图
注意
只允许多层继承不能多重继承。
在Java中只允许单继承,不能使用多重继承,即:一个子类只能继承一个父类,如图6-3所示;允许进行多层继承,即:一个子类可以有一个父类,一个父类还可以有一个父类,如图6-4所示。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_21564.jpg?sign=1739283045-Hj0DILREjqnsxl5mVFTqJwHgSM7AwcKZ-0-233254a2937bdff9fdbc4674f97163fe)
图6-3 多重继承
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P163_21565.jpg?sign=1739283045-XJtw1bteqBrzETM1JF6bqbZM8ri9NcgZ-0-a3b4b36bee47ccdd6cd4f6778e77cb09)
图6-4 多层继承
实例1:错误的继承代码
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124310.jpg?sign=1739283045-3u71jhro8g4vmkCR4gcy5Utm6qGGVy42-0-161187fa248ae1fdd1f39d2d36c0eb0c)
由上面的代码可以发现类C同时继承了类A与类B,也就是说C类同时继承了两个父类,这是不允许的。
实例2:多层继承
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124312.jpg?sign=1739283045-25lri6wotDrJxHgvBQmvA4BbRINWjOUr-0-1972a7550c1fbc728c4bf9cab43e8afc)
由上面可以发现类B继承了类A,而类C又继承了类B,也就是说类B是类A的子类,而类C则是类A的孙子类。
同样,在类图的表示中对于继承也是有明确的要求的,可以使用如下形式的图形表示类的继承关系。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_21575.jpg?sign=1739283045-B39yJ8YcCHAhPbFUusIA3My16cto7s1Q-0-7fb6fb8d7481a63aacecd55de9dc95a1)
图6-5 继承的类图表示
提示
继承的子类有时也称为派生类。
使用extends关键字可以实现继承的关系,但是这个关键字的本身含义是“扩展”,更准确地说是一个类扩展已有类的功能,在其他的书中也会经常把子类称为派生类。
在使用继承的时候也应注意的是:子类是不能直接访问父类中的私有成员的,但是子类可以调用父类中的非私有方法,但是不能直接调用父类中的私有成员,如图6-6所示。
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124315.jpg?sign=1739283045-AfEAfu6PKDXJ2V4KlIpF2Pq9GEXAvNOn-0-949ca7a10ee43d8076a8bc9f9e373a40)
图6-6 子类访问的限制
【例6.5】子类访问限制
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P164_124316.jpg?sign=1739283045-NNxpS9rLhITXu1MzTSDLDtDNGJZJGDqv-0-5958bb460582192161512ce126062ac2)
编译时错误:
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P165_124317.jpg?sign=1739283045-cK3nmXe9pYhiZgk8ntQ5MYU2EVGd6Uo7-0-f83148b23f5bb663ba9b562abf5201fc)
上面的代码中,子类直接访问了父类中的私有属性,所以在编译的时候编译器会通知用户name和age属性无法访问,如果此时不直接访问name()或age()属性,而是直接通过setter()或getter()方法调用的话,就可以访问。
【例6.6】通过getter方法间接取得属性内容
![](https://epubservercos.yuewen.com/DE8B7B/15253389304122106/epubprivate/OEBPS/Images/Figure-P165_124318.jpg?sign=1739283045-hZdrDXF1imO3OQXFF1bODXixqtgRfxbz-0-43e8e122fe775ad7f1c87d262745a77e)