Java三大特性之繼承詳解
概述
由來(lái)
多個(gè)類(lèi)中存在相同屬性和行為時(shí),將這些內(nèi)容抽取到單獨(dú)一個(gè)類(lèi)中,那么多個(gè)類(lèi)無(wú)需再定義這些屬性和行為,只要繼承那一個(gè)類(lèi)即可。如圖所示:

其中,多個(gè)類(lèi)可以稱(chēng)為子類(lèi),單獨(dú)那一個(gè)類(lèi)稱(chēng)為父類(lèi)、超類(lèi)(superclass)或者基類(lèi)。 繼承描述的是事物之間的所屬關(guān)系,這種關(guān)系是: is-a 的關(guān)系。例如,圖中兔子屬于食草動(dòng)物,食草動(dòng)物屬于動(dòng) 物。可見(jiàn),父類(lèi)更通用,子類(lèi)更具體。我們通過(guò)繼承,可以使多種事物之間形成一種關(guān)系體系。
定義
繼承:就是子類(lèi)繼承父類(lèi)的屬性和行為,使得子類(lèi)對(duì)象具有與父類(lèi)相同的屬性、相同的行為。子類(lèi)可以直接 訪(fǎng)問(wèn)父類(lèi)中的非私有的屬性和行為。
好處
- 提高代碼的復(fù)用性。
- 類(lèi)與類(lèi)之間產(chǎn)生了關(guān)系,是多態(tài)的前提。
繼承的格式
通過(guò) extends 關(guān)鍵字,可以聲明一個(gè)子類(lèi)繼承另外一個(gè)父類(lèi),定義格式如下:
class 父類(lèi) {
...
}
class 子類(lèi) extends 父類(lèi) {
...
}
繼承演示,代碼如下:
/*
* 定義員工類(lèi)Employee,做為父類(lèi)
*/
class Employee {
String name; // 定義name屬性
// 定義員工的工作方法
public void work() {
System.out.println("盡心盡力地工作");
}
}
/*
* 定義講師類(lèi)Teacher 繼承 員工類(lèi)Employee
*/
class Teacher extends Employee {
// 定義一個(gè)打印name的方法
public void printName() {
System.out.println("name=" + name);
}
}
/*
* 定義測(cè)試類(lèi)
*/
public class ExtendDemo01 {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)講師類(lèi)對(duì)象
Teacher t = new Teacher();
// 為該員工類(lèi)的name屬性進(jìn)行賦值
t.name = "小明";
// 調(diào)用該員工的printName()方法
t.printName(); // name = 小明
// 調(diào)用Teacher類(lèi)繼承來(lái)的work()方法
t.work(); // 盡心盡力地工作
}
}
繼承后的特點(diǎn)—成員變量
當(dāng)類(lèi)之間產(chǎn)生了關(guān)系后,其中各類(lèi)中的成員變量,又產(chǎn)生了哪些影響呢?
成員變量不重名
如果子類(lèi)父類(lèi)中出現(xiàn)不重名的成員變量,這時(shí)的訪(fǎng)問(wèn)是沒(méi)有影響的。代碼如下:
class Fu {
// Fu中的成員變量。
int num = 5;
}
class Zi extends Fu {
// Zi中的成員變量
int num2 = 6;
// Zi中的成員方法
public void show() {
// 訪(fǎng)問(wèn)父類(lèi)中的num,
System.out.println("Fu num="+num); // 繼承而來(lái),所以直接訪(fǎng)問(wèn)。
// 訪(fǎng)問(wèn)子類(lèi)中的num2
System.out.println("Zi num2="+num2);
}
}
class ExtendDemo02 {
public static void main(String[] args) {
// 創(chuàng)建子類(lèi)對(duì)象
Zi z = new Zi();
// 調(diào)用子類(lèi)中的show方法
z.show();
}
}演示結(jié)果:
Fu num = 5
Zi num2 = 6
成員變量重名
如果子類(lèi)父類(lèi)中出現(xiàn)重名的成員變量,這時(shí)的訪(fǎng)問(wèn)是有影響的。代碼如下:
class Fu {
// Fu中的成員變量。
int num = 5;
}
class Zi extends Fu {
// Zi中的成員變量
int num = 6;
public void show() {
// 訪(fǎng)問(wèn)父類(lèi)中的num
System.out.println("Fu num=" + num);
// 訪(fǎng)問(wèn)子類(lèi)中的num
System.out.println("Zi num=" + num);
}
}
class ExtendsDemo03 {
public static void main(String[] args) {
// 創(chuàng)建子類(lèi)對(duì)象
Zi z = new Zi();
// 調(diào)用子類(lèi)中的show方法
z.show();
}
}
演示結(jié)果:
Fu num = 6
Zi num = 6
子父類(lèi)中出現(xiàn)了同名的成員變量時(shí),在子類(lèi)中需要訪(fǎng)問(wèn)父類(lèi)中非私有成員變量時(shí),需要使用super 關(guān)鍵字,修飾 父類(lèi)成員變量 。 使用格式:
super.父類(lèi)成員變量名
子類(lèi)方法需要修改,代碼如下:
class Zi extends Fu {
// Zi中的成員變量
int num = 6;
public void show() {
//訪(fǎng)問(wèn)父類(lèi)中的num
System.out.println("Fu num=" + super.num);
//訪(fǎng)問(wèn)子類(lèi)中的num
System.out.println("Zi num=" + this.num);
}
}
演示結(jié)果:
Fu num = 5
Zi num = 6
小貼士:Fu 類(lèi)中的成員變量是非私有的,子類(lèi)中可以直接訪(fǎng)問(wèn)。若Fu 類(lèi)中的成員變量私有了,子類(lèi)是不能 直接訪(fǎng)問(wèn)的。通常編碼時(shí),我們遵循封裝的原則,使用private修飾成員變量,那么如何訪(fǎng)問(wèn)父類(lèi)的私有成員 變量呢?對(duì)!可以在父類(lèi)中提供公共的getXxx方法和setXxx方法。
繼承后的特點(diǎn)—成員方法
當(dāng)類(lèi)之間產(chǎn)生了關(guān)系,其中各類(lèi)中的成員方法,又產(chǎn)生了哪些影響呢?
成員方法不重名
如果子類(lèi)父類(lèi)中出現(xiàn)不重名的成員方法,這時(shí)的調(diào)用是沒(méi)有影響的。對(duì)象調(diào)用方法時(shí),會(huì)先在子類(lèi)中查找有沒(méi)有對(duì)應(yīng)的方法,若子類(lèi)中存在就會(huì)執(zhí)行子類(lèi)中的方法,若子類(lèi)中不存在就會(huì)執(zhí)行父類(lèi)中相應(yīng)的方法。代碼如下:
class Fu{
public void show(){
System.out.println("Fu類(lèi)中的show方法執(zhí)行");
}
}
class Zi extends Fu{
public void show2(){
System.out.println("Zi類(lèi)中的show2方法執(zhí)行");
}
}
public class ExtendsDemo04{
public static void main(String[] args) {
Zi z = new Zi();
//子類(lèi)中沒(méi)有show方法,但是可以找到父類(lèi)方法去執(zhí)行
z.show();
z.show2();
}
}
成員方法重名—重寫(xiě)(Override)
如果子類(lèi)父類(lèi)中出現(xiàn)重名的成員方法,這時(shí)的訪(fǎng)問(wèn)是一種特殊情況,叫做方法重寫(xiě) (Override)。 方法重寫(xiě) :子類(lèi)中出現(xiàn)與父類(lèi)一模一樣的方法時(shí)(返回值類(lèi)型,方法名和參數(shù)列表都相同),會(huì)出現(xiàn)覆蓋效 果,也稱(chēng)為重寫(xiě)或者復(fù)寫(xiě)。聲明不變,重新實(shí)現(xiàn)。 代碼如下:
class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
//子類(lèi)重寫(xiě)了父類(lèi)的show方法
public void show() {
System.out.println("Zi show");
}
}
public class ExtendsDemo05{
public static void main(String[] args) {
Zi z = new Zi();
// 子類(lèi)中有show方法,只執(zhí)行重寫(xiě)后的show方法
z.show(); // Zi show
}
}
重寫(xiě)的應(yīng)用
子類(lèi)可以根據(jù)需要,定義特定于自己的行為。既沿襲了父類(lèi)的功能名稱(chēng),又根據(jù)子類(lèi)的需要重新實(shí)現(xiàn)父類(lèi)方法,從而進(jìn)行擴(kuò)展增強(qiáng)。比如新的手機(jī)增加來(lái)電顯示頭像的功能,代碼如下:
class Phone {
public void sendMessage(){
System.out.println("發(fā)短信");
}
public void call(){
System.out.println("打電話(huà)");
}
public void showNum(){
System.out.println("來(lái)電顯示號(hào)碼");
}
}
//智能手機(jī)類(lèi)
class NewPhone extends Phone {
//重寫(xiě)父類(lèi)的來(lái)電顯示號(hào)碼功能,并增加自己的顯示姓名和圖片功能
public void showNum(){
//調(diào)用父類(lèi)已經(jīng)存在的功能使用super
super.showNum();
//增加自己特有顯示姓名和圖片功能
System.out.println("顯示來(lái)電姓名");
System.out.println("顯示頭像");
}
}
public class ExtendsDemo06 {
public static void main(String[] args) {
// 創(chuàng)建子類(lèi)對(duì)象
NewPhone np = new NewPhone();
// 調(diào)用父類(lèi)繼承而來(lái)的方法
np.call();
// 調(diào)用子類(lèi)重寫(xiě)的方法
np.showNum();
}
}
小貼士:這里重寫(xiě)時(shí),用到super.父類(lèi)成員方法,表示調(diào)用父類(lèi)的成員方法。
注意事項(xiàng)
- 子類(lèi)方法覆蓋父類(lèi)方法,必須要保證權(quán)限大于等于父類(lèi)權(quán)限。
- 子類(lèi)方法覆蓋父類(lèi)方法,返回值類(lèi)型、函數(shù)名和參數(shù)列表都要一模一樣。
繼承后的特點(diǎn)—構(gòu)造方法
當(dāng)類(lèi)之間產(chǎn)生了關(guān)系,其中各類(lèi)中的構(gòu)造方法,又產(chǎn)生了哪些影響呢? 首先我們要回憶兩個(gè)事情,構(gòu)造方法的定義格式和作用。
- 構(gòu)造方法的名字是與類(lèi)名一致的。所以子類(lèi)是無(wú)法繼承父類(lèi)構(gòu)造方法的。
- 構(gòu)造方法的作用是初始化成員變量的。所以子類(lèi)的初始化過(guò)程中,必須先執(zhí)行父類(lèi)的初始化動(dòng)作。子類(lèi)的構(gòu)
造方法中默認(rèn)有一個(gè)super() ,表示調(diào)用父類(lèi)的構(gòu)造方法,父類(lèi)成員變量初始化后,才可以給子類(lèi)使用。代碼如下:
class Fu {
private int n;
Fu(){
System.out.println("Fu()");
}
}
class Zi extends Fu {
Zi(){
// super(),調(diào)用父類(lèi)構(gòu)造方法
super();
System.out.println("Zi()");
}
}
public class ExtendsDemo07{
public static void main (String args[]){
Zi zi = new Zi();
}
}
輸出結(jié)果:
Fu()
Zi()
到此這篇關(guān)于Java三大特性之繼承詳解的文章就介紹到這了,更多相關(guān)Java繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
劍指Offer之Java算法習(xí)題精講排列與N叉樹(shù)
跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03
Spring MVC下 bootStrap服務(wù)器分頁(yè)代碼
因?yàn)镾pring 對(duì)于ajax直接返回對(duì)象,到了WEB頁(yè)面就轉(zhuǎn)換成json 所以不需要使用JSON轉(zhuǎn)換封裝可以直接使用。接下來(lái)通過(guò)本文給大家分享Spring MVC下 bootStrap服務(wù)器分頁(yè)代碼,需要的的朋友參考下2017-03-03
關(guān)于各種排列組合java算法實(shí)現(xiàn)方法
這篇文章介紹了幾種用JAVA實(shí)現(xiàn)的排列組合算法,有需要的朋友可以參考一下2013-06-06
springboot獲取真實(shí)ip地址的方法實(shí)例
在使用springboot時(shí),需要獲取訪(fǎng)問(wèn)客戶(hù)端的IP地址,所以下面這篇文章主要給大家介紹了關(guān)于springboot獲取真實(shí)ip地址的相關(guān)資料,需要的朋友可以參考下2022-06-06
MyBatis深入解讀動(dòng)態(tài)SQL的實(shí)現(xiàn)
動(dòng)態(tài) SQL 是 MyBatis 的強(qiáng)大特性之一。如果你使用過(guò) JDBC 或其它類(lèi)似的框架,你應(yīng)該能理解根據(jù)不同條件拼接 SQL 語(yǔ)句有多痛苦,例如拼接時(shí)要確保不能忘記添加必要的空格,還要注意去掉列表最后一個(gè)列名的逗號(hào)。利用動(dòng)態(tài) SQL,可以徹底擺脫這種痛苦2022-04-04
SpringBoot導(dǎo)入導(dǎo)出數(shù)據(jù)實(shí)現(xiàn)方法詳解
這篇文章主要介紹了SpringBoot導(dǎo)入導(dǎo)出數(shù)據(jù)實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-12-12

