一、本單元知識點概述
(Ⅰ)知識點概述

二、本單元目標
(Ⅰ)重點知識目標
1.方法重寫
2.Super和this關鍵字
3.抽象類
(Ⅱ)能力目標
1.能夠寫出類的繼承格式
2.能夠說出super可以解決的問題
3.寫出抽象類和寫出抽象方法的格式
三、本單元知識詳講
13.1 繼承
13.1.1 繼承的由來★★★
多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那么多個類無需再定義這些屬性和行為,只要 繼承那一個類即可,如圖所示:

其中,多個類可以稱為子類,單獨那一個類稱為父類、超類(superclass)或者基類, 繼承描述的是事物之間的所屬關系,這種關系是: is-a 的關系,例如,圖中兔子屬于食草動物,食草動物屬于動 物,可見,父類更通用,子類更具體,我們通過繼承,可以使多種事物之間形成一種關系體系,
13.1.2 繼承的定義★★★
-
繼承:就是子類繼承父類的屬性和行為,使得子類物件具有與父類相同的屬性、相同的行為,子類可以直接 訪問父類中的非私有的屬性和行為,
13.1.3 繼承的好處★★★★
-
提高代碼的復用性,
-
類與類之間產生了關系,是多型的前提,
13.1.4 繼承的格式★★★
通過 extends 關鍵字,可以宣告一個子類繼承另外一個父類,定義格式如下:
1 class 父類 { 2 ... 3 } 4 class 子類 extends 父類 { 5 ... 6 }
繼承演示,代碼如下:
1 /* 2 * 定義員工類Employee,做為父類 3 */ 4 class Employee { 5 String name; // 定義name屬性 6 // 定義員工的作業方法 7 public void work() { 8 System.out.println("盡心盡力地作業"); 9 } 10 } 11 12 /* 13 * 定義講師類Teacher 繼承 員工類Employee 14 */ 15 class Teacher extends Employee { 16 // 定義一個列印name的方法 17 public void printName() { 18 System.out.println("name=" + name); 19 } 20 } 21 22 /* 23 * 定義測驗類 24 */ 25 public class ExtendDemo01 { 26 public static void main(String[] args) { 27 // 創建一個講師類物件 28 Teacher t = new Teacher(); 29 // 為該員工類的name屬性進行賦值 30 t.name = "小明"; 31 // 呼叫該員工的printName()方法 32 t.printName(); // name = 小明 33 // 呼叫Teacher類繼承來的work()方法 34 t.work(); // 盡心盡力地作業 35 } 36 }
13.1.5 繼承的特點 ★★★★
-
Java只支持單繼承,不支持多繼承,
//一個類只能有一個父類,不可以有多個父類, class C extends A{} //ok class C extends A,B... //error
-
Java支持多層繼承(繼承體系),
class A{} class B extends A{} class C extends B{}
繼承后的特點——成員變數
當類之間產生了關系后,其中各類中的成員變數,又產生了哪些影響呢?
-
成員變數不重名
1 class Fu { 2 // Fu中的成員變數, 3 int num = 5; 4 } 5 class Zi extends Fu { 6 int num2 = 6; 7 // Zi中的成員方法 8 public void show() { 9 // 訪問父類中的num, 10 System.out.println("Fu num="+num); // 繼承而來,所以直接訪問, 11 // 訪問子類中的num2 12 System.out.println("Zi num2="+num2); 13 } 14 } 15 class ExtendDemo02 { 16 public static void main(String[] args) { 17 // 創建子類物件 18 Zi z = new Zi(); 19 // 呼叫子類中的show方法 20 z.show(); 21 } 22 } 23 演示結果: 24 Fu num = 5 25 Zi num2 = 6
-
成員變數重名
如果子類父類中出現重名的成員變數,這時的訪問是有影響的,代碼如下:
1 class Fu { 2 // Fu中的成員變數, 3 int num = 5; 4 } 5 class Zi extends Fu { 6 // Zi中的成員變數 7 int num = 6; 8 public void show() { 9 // 訪問父類中的num 10 System.out.println("Fu num=" + num); 11 // 訪問子類中的num 12 System.out.println("Zi num=" + num); 13 } 14 } 15 class ExtendsDemo03 { 16 public static void main(String[] args) { 17 // 創建子類物件 18 Zi z = new Zi(); 19 // 呼叫子類中的show方法 20 z.show(); 21 } 22 } 23 演示結果: 24 Fu num = 6 25 Zi num = 6
子父類中出現了同名的成員變數時,在子類中需要訪問父類中非私有成員變數時,需要使用 super關鍵字,修飾 父類成員變數,類似于之前學過的 this , 使用格式:
super.父類成員變數名
子類方法需要修改,代碼如下:
1 class Zi extends Fu { 2 // Zi中的成員變數 3 int num = 6; 4 public void show() { 5 //訪問父類中的num 6 System.out.println("Fu num=" + super.num); 7 //訪問子類中的num 8 System.out.println("Zi num=" + this.num); 9 } 10 } 11 演示結果: 12 Fu num = 5 13 Zi num = 6
小貼士:Fu 類中的成員變數是非私有的,子類中可以直接訪問,若Fu 類中的成員變數私有了,子類是不能 直接訪問的,通常編碼時,我們遵循封裝的原則,使用private修飾成員變數,那么如何訪問父類的私有成員 變數呢?對!可以在父類中提供公共的getXxx方法和setXxx方法,
繼承后的特點——成員方法
當類之間產生了關系,其中各類中的成員方法,又產生了哪些影響呢?
-
成員方法不重名
如果子類父類中出現不重名的成員方法,這時的呼叫是沒有影響的,物件呼叫方法時,會先在子類中查找有沒有對 應的方法,若子類中存在就會執行子類中的方法,若子類中不存在就會執行父類中相應的方法,代碼如下:
1 class Fu{ 2 public void show(){ 3 System.out.println("Fu類中的show方法執行"); 4 } 5 } 6 class Zi extends Fu{ 7 public void show2(){ 8 System.out.println("Zi類中的show2方法執行"); 9 } 10 } 11 public class ExtendsDemo04{ 12 public static void main(String[] args) { 13 Zi z = new Zi(); 14 //子類中沒有show方法,但是可以找到父類方法去執行 15 z.show(); 16 z.show2(); 17 } 18 }
成員方法重名——重寫(Override)
如果子類父類中出現重名的成員方法,這時的訪問是一種特殊情況,叫做方法重寫 (Override),
-
方法重寫 :子類中出現與父類一模一樣的方法時(回傳值型別,方法名和引數串列都相同),會出現覆寫效 果,也稱為重寫或者復寫,宣告不變,重新實作,
代碼如下:
1 class Fu { 2 public void show() { 3 System.out.println("Fu show"); 4 } 5 } 6 7 class Zi extends Fu { 8 //子類重寫了父類的show方法 9 public void show() { 10 System.out.println("Zi show"); 11 } 12 } 13 public class ExtendsDemo05{ 14 public static void main(String[] args) { 15 Zi z = new Zi(); 16 // 子類中有show方法,只執行重寫后的show方法 17 z.show(); // Zi show 18 } 19 }
重寫的應用
子類可以根據需要,定義特定于自己的行為,既沿襲了父類的功能名稱,又根據子類的需要重新實作父類方法,從 而進行擴展增強,比如新的手機增加來電顯示頭像的功能,代碼如下:
1 class Phone { 2 public void sendMessage(){ 3 System.out.println("發短信"); 4 } 5 6 public void call(){ 7 System.out.println("打電話"); 8 } 9 10 public void showNum(){ 11 System.out.println("來電顯示號碼"); 12 } 13 } 14 //智能手機類 15 class NewPhone extends Phone { 16 //重寫父類的來電顯示號碼功能,并增加自己的顯示姓名和圖片功能 17 public void showNum(){ 18 //呼叫父類已經存在的功能使用super 19 uper.showNum(); 20 //增加自己特有顯示姓名和圖片功能 21 System.out.println("顯示來電姓名"); 22 System.out.println("顯示頭像"); 23 } 24 } 25 26 public class ExtendsDemo06 { 27 public static void main(String[] args) { 28 // 創建子類物件 29 NewPhone np = new NewPhone(); 30 // 呼叫父類繼承而來的方法 31 np.call(); 32 // 呼叫子類重寫的方法 33 np.showNum(); 34 } 35 }
小貼士:這里重寫時,用到super.父類成員方法,表示呼叫父類的成員方法,
-
-
注意事項
-
子類方法覆寫父類方法,必須要保證權限大于等于父類權限,
-
子類方法覆寫父類方法,回傳值型別、函式名和引數串列都要一模一樣,
-
-
-
繼承后的特點——構造方法
當類之間產生了關系,其中各類中的構造方法,又產生了哪些影響呢? 首先我們要回憶兩個事情,構造方法的定義格式和作用,
-
構造方法的名字是與類名一致的,所以子類是無法繼承父類構造方法的,
-
構造方法的作用是初始化成員變數的,所以子類的初始化程序中,必須先執行父類的初始化動作,子類的構 造方法中默認有一個
super(),表示呼叫父類的構造方法,父類成員變數初始化后,才可以給子類使用,代 碼如下:
-
1 class Fu { 2 private int n; 3 Fu(){ 4 System.out.println("Fu()"); 5 } 6 } 7 class Zi extends Fu { 8 Zi(){ 9 // super(),呼叫父類構造方法 10 super(); 11 System.out.println("Zi()"); 12 } 13 } 14 public class ExtendsDemo07{ 15 public static void main (String args[]){ 16 Zi zi = new Zi(); 17 } 18 } 19 輸出結果: 20 Fu() 21 Zi()
13.2 Super和This
13.2.1 super和this的含義 ★★★
-
super :代表父類的存盤空間標識(可以理解為父親的參考),
-
this :代表當前物件的參考(誰呼叫就代表誰),
13.2.2 super和this的用法★★★★
-
訪問成員
this.成員變數 ‐‐ 本類的 super.成員變數 ‐‐ 父類的 this.成員方法名() ‐‐ 本類的 super.成員方法名() ‐‐ 父類的
用法演示,代碼如下:
1 class Animal { 2 public void eat() { 3 System.out.println("animal : eat"); 4 } 5 } 6 class Cat extends Animal { 7 public void eat() { 8 System.out.println("cat : eat"); 9 } 10 public void eatTest() { 11 this.eat(); // this 呼叫本類的方法 12 super.eat(); // super 呼叫父類的方法 13 } 14 } 15 public class ExtendsDemo08 { 16 public static void main(String[] args) { 17 Animal a = new Animal(); 18 a.eat(); 19 Cat c = new Cat(); 20 c.eatTest(); 21 } 22 } 23 輸出結果為: 24 animal : eat 25 cat : eat 26 animal : eat
-
訪問構造方法
this(...) ‐‐ 本類的構造方法 super(...) ‐‐ 父類的構造方法
子類的每個構造方法中均有默認的super(),呼叫父類的空參構造,手動呼叫父類構造會覆寫默認的super(), super() 和 this() 都必須是在構造方法的第一行,所以不能同時出現,
13.3 抽象類
13.3.1 抽象類的由來★★
父類中的方法,被它的子類們重寫,子類各自的實作都不盡相同,那么父類的方法宣告和方法主體,只有宣告還有 意義,而方法主體則沒有存在的意義了,我們把沒有方法主體的方法稱為抽象方法,Java語法規定,包含抽象方法 的類就是抽象類,
13.3.2 抽象類的定義★★★
-
抽象方法 : 沒有方法體的方法,
-
抽象類:包含抽象方法的類,
13.3.3 抽象方法★★★
使用 abstract 關鍵字修飾方法,該方法就成了抽象方法,抽象方法只包含一個方法名,而沒有方法體,
定義格式:
修飾符 abstract 回傳值型別 方法名 (引數串列);
代碼舉例:
public abstract void run();
13.3.4 抽象類★★★
如果一個類包含抽象方法,那么該類必須是抽象類,
定義格式:
abstract class 類名字 { }
代碼舉例:
public abstract class Animal { public abstract void run(); }
13.3.5 抽象的使用★★★
繼承抽象類的子類必須重寫父類所有的抽象方法,否則,該子類也必須宣告為抽象類,最終,必須有子類實作該父 類的抽象方法,否則,從最初的父類到最終的子類都不能創建物件,失去意義,
代碼舉例:
1 public class Cat extends Animal { 2 public void run (){ 3 System.out.println("小貓在墻頭走~~~"); 4 } 5 } 6 7 public class CatTest { 8 public static void main(String[] args) { 9 // 創建子類物件 10 Cat c = new Cat(); 11 // 呼叫run方法 12 c.run(); 13 } 14 } 15 輸出結果: 16 小貓在墻頭走~~~
13.3.6 注意事項有哪些★★
關于抽象類的使用,以下為語法上要注意的細節,雖然條目較多,但若理解了抽象的本質,無需死記硬背,
-
抽象類不能創建物件,如果創建,編譯無法通過而報錯,只能創建其非抽象子類的物件
-
理解:假設創建了抽象類的物件,呼叫抽象的方法,而抽象方法沒有具體的方法體,沒有意義,
-
-
抽象類中,可以有構造方法,是供子類創建物件時,初始化父類成員使用的,
-
理解:子類的構造方法中,有默認的super(),需要訪問父類構造方法,
-
-
抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類,
-
理解:未包含抽象方法的抽象類,目的就是不想讓呼叫者創建該類物件,通常用于某些特殊的類結構設 計,
-
-
抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報錯,除非該子類也是抽象 類,
-
理解:假設不重寫所有抽象方法,則類中可能包含抽象方法,那么創建物件后,呼叫抽象的方法,沒有 意義,
-
四、本單元知識總結
1.繼承的好處、格式及特點,
2.super和this關鍵字的含義和用法,
3.抽象類中抽象的使用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/310337.html
標籤:Java
