Java基礎複習第八天:繼承、過載、this與super、多型、static
一 繼承
1.繼承的由來
多個類中有相同成員變數和成員方法,那麼我們會把這些共性抽取到另外一個類中,
這時多個類只需要繼承剛剛抽取出來這個類即可
2.父類 和 子類
一個類A 繼承了 類B,那麼 類B稱為父類/超類/基類(superclass)
類A稱為子類/派生類(subclass)
3.繼承的格式:
public class Fu{ //成員變數 //成員方法 } public class Zi extends Fu{ 子類自動擁有父類的所有成員變數和成員方法 (私有的不能直接使用) } 好處:a.提高程式碼的複用性 b.為多型提供了前提
4.繼承後子父類成員方法的特點
如果子父類的成員方法不同名,那麼子類呼叫成員方法時,沒有任何歧義
如果子父類的成員方法同名,那麼子類呼叫成員方法時,優先呼叫子類自己的成員方法
如果把子類那個成員方法註釋掉,才會呼叫父類繼承的
如果把父類那個成員方法也註釋掉,那麼程式會報錯
總結: 無論是成員變數 還是 成員方法,子類有優先訪問子類自己的,子類沒有才會訪問父類的(就近原則),父類沒有才會報錯!!!!
5.方法的重寫
方法的過載(overload): 在同一個類中,有方法名一樣,但是引數列表不一樣的多個方法 方法的重寫(override): 在子父類中,出現除了方法體其他都一樣的方法,此時子類中這個方法稱為方法的重寫 什麼時候需要方法的重寫: 當子類繼承父類的方法後,發現父類的方法功能不足,那麼子類就可以重寫該方法 在重寫該方法時,如果某一部分功能父類已經實現了,只需要通過super.方法名 呼叫父類已經實現功能即可 其他未實現的功能,子類在自己新增上去
6.關鍵字 this 和 super
this的作用: 區分區域性變數和成員變數的同名問題
super的作用: 區分本類成員變數和父類成員變數同名問題
格式:
this.成員變數 訪問本類的成員變數
super.成員變數 訪問父類的成員變數
this.方法名() 呼叫本類自己的成員方法
super.方法名() 呼叫父類的成員方法
7.繼承後構造方法的特點
構造方法的特點: 不寫任何返回值型別,方法名必須和類名一樣 構造方法子類是不能繼承,跟沒有繼承的說法 特點: 子類的任何構造方法,第一行預設會使用super()呼叫父類的無參構造 思考:能不能不呼叫父類的無參構造,而是呼叫父類的有參構造??? 能!!!但是必須程式設計師手動呼叫super(引數);
8.構造方法總結
super() 呼叫父類的無參構造
super(引數) 呼叫父類的有參構造
this();呼叫子類自己的無參構造
this(引數);呼叫子類自己的有參構造
無論是this()還是super()都必須寫在第一行,而且不能同時出現
9.繼承之後 子類物件的記憶體圖
父類空間優先於子類物件產生
在每次建立子類物件時,先初始化父類空間,再建立其子類物件本身。目的在於子類物件中包含了其對應的父類空間,
便可以包含其父類的成員,如果父類成員非private修飾,則子類可以隨意使用父類成員
11. 繼承的特點
a.java中類和類之間叫單繼承 (一個子類 只能有一個親爹)
b.java中類和類之間可以多層繼承(一個子類 只能有一個父類 該父類也可以有自己的父類)
二.多型
1.多型的概念
一個物件的多種形態:
H2O
固態: 冰,雪花
液態:溪水,海水
氣態:蒸汽
一個學生
在家: 兒子,父母
在社會: 員工,老闆,包工頭
在學校: 學生,學霸,學渣,學神
2.多型的前提
a.繼承 或者 實現
b.必須有方法的重寫(Override)
3.多型的體現
語言表達:父類型別的變數 指向了 子類型別的物件
程式碼表達:Fu ff = new Zi();
多型的賦值:直接賦值:
父類型別 變數名 = new 子類型別();
爺爺型別 變數名 = new 孫子型別();
爺爺型別 變數名 = new 父類型別();
多型的賦值:間接賦值:
子類型別 變數名 = new 子類物件();
父類型別 物件名 = 變數名;
多型的賦值:引數賦值:
子類型別 物件名 = new 子類型別();
method(物件名);
public static void method(父類型別 變數名){
父類型別 變數名 = new 子類型別();
}
4.多型呼叫方法時的特點**************
編譯階段 看父類
執行階段 看子類
多型只能呼叫子父類共有的方法,不能呼叫子類特有的方法
5.多型的好處***********
提高程式擴充套件性(靈活性)
6.多型的弊端
多型只能呼叫子父類共有的方法,不能呼叫子類特有的方法
7.多型弊端的解決方案–轉型
資料型別轉換---基本型別
自動轉換 --- double d = 10;
強制轉換 --- int a = (int)3.14;
轉型---引用型別
向上轉型: Animal an = new Cat(); //也就是多型
向下轉換: Cat cc = (Cat)an;
8.轉型的異常
Animal a = new Cat(); //多型,向上轉型
a.eat(); // 呼叫的是 Cat 的 eat
Dog d = (Dog)a; //執行報錯:ClassCastException (型別轉換異常)
//因為a之前儲存的是cat型別不是Dog型別
d.watchHouse();
9.轉型異常的解決方案
運算子 instanceof
格式:
物件 instanceof 型別
結果:
如果物件是屬於右邊的型別 那麼返回true
如果物件不屬於右邊的型別 那麼返回false
public class Test {
public static void main(String[] args) {
// 向上轉型
Animal a = new Cat();
a.eat(); // 呼叫的是 Cat 的 eat
// 判斷a是否是Cat型別
if (a instanceof Cat){
Cat c = (Cat)a; //向下轉型
c.catchMouse(); // 呼叫的是 Cat 的 catchMouse
} else if (a instanceof Dog){//判斷a是否是Dog型別
Dog d = (Dog)a; //向下轉型
三 static關鍵字
1.static關鍵字的用法和作用
用法:static可以修飾類的成員
格式:
public class 類名{
static int age;
public static void eat(){
}
}
static的作用:
被static修飾的成員,稱為類成員,屬於類,不屬於某個物件
2.static修飾成員變數—類變數.靜態變數
特點: 被static修飾的成員變數,不屬於物件,屬於類,在記憶體中只有一份,被所有物件共享
記憶體圖:
https://blog.csdn.net/sapodilla/article/details/49494165
我的圖,上傳失敗…
推薦訪問靜態變數的方式:
物件名.靜態成員變數(不推薦)
類名.靜態成員變數(推薦)
3.static修飾成員方法—類方法,靜態方法
被static修飾的方法,可以直接使用類名呼叫,不需要使用物件呼叫(工具類)
推薦呼叫靜態方法的方式
物件名.靜態方法名();//不推薦
類名.靜態方法名();//推薦
4.擴充套件:
靜態和非靜態的相互訪問
結論:
靜態與靜態,非靜態與非靜態之間可以相互訪問
但是 靜態不能訪問非靜態 非靜態卻可以訪問靜態
為什麼:因為他們的生命週期不一樣
靜態: 隨著類載入而存在,出現的時間早(秦始皇)
非靜態:隨著物件的建立而存在,出現的時間晚(我們)
5.static還可以修飾程式碼塊—靜態程式碼塊
a.定義位置
直接定義在類的內部
格式:
public class 類名{
static{
這裡就是靜態程式碼塊中的程式碼
}
}
b.特點
靜態程式碼塊,隨著類的載入而執行,而且只會執行一次
所以執行優先順序,高於構造,高於main方法
c.作用
用來初始化一些資料(坦克大戰,資料庫驅動)
6.回顧
1)static可以修飾哪些成員?
a.成員變數:
該成員變數 變成類變數,類變數在記憶體只有一個,被所有物件共享
b.成員方法
該成員變數 變數類方法,可以通過類名直接呼叫方法(製作工具類)
c.靜態程式碼塊
隨著類的載入立刻執行(初始化一些資料,一些靜態變數)
2).使用static修飾的成員可以怎樣被訪問?
物件名.靜態變數名
物件名.靜態方法名()
=============以上可以通過物件訪問,但是不推薦================
類名.靜態變數名
類名.靜態方法名();
3).以下哪些可以使用static修飾:
A).類 B).成員屬性 C).成員方法 D).區域性變數 E).構造方法
ABC
4)static程式碼塊什麼時候會被執行?
隨著類載入 立刻執行
5).如果一個類中同時定義了"靜態程式碼塊"和"構造方法",當第一次建立這個類的物件時,它們會被怎樣執行?
先靜態程式碼塊 再執行構造方法
第二次再建立物件時,它們會被怎樣執行?
只執行構造方法,不執行靜態程式碼塊
四.練習
1. 使用繼承的方式,在子類特有的show方法中列印父類int型別成員變數的值;
2.使用繼承的方式完成某人自我介紹的功能;
具體要求:
1:父類中使用私有的成員變量表示姓名和年齡;
2:父類中用show方法表示自我介紹的行為,具體內容是:
我叫:xxx,今年xx歲;
3:在子類的show方法中呼叫父類的show方法;
3.使用程式碼模擬學生和老師資訊管理系統;
具體要求:
1:老師和學生都是人,都包含姓名和年齡屬性(要求私有),都包含自我介紹方法show,在show方法中展示個人資訊.例如:
我是xxx,今年xx歲.
2:老師有講課方法teach,方法的內容是: 我是一名老師,我在講課;
3:學生有學習方法study,方法的內容是: 我是一名學生,我在學習;
4:編寫測試類,要求建立老師和學生物件的時候,使用多型方式,且呼叫每個物件的show方法.
5:若是老師呼叫teach方法;若是學生呼叫study方法.
列印效果:
我是張老師,今年35歲
我是一名老師,我在講課
我是小明,今天20歲
我是一名學生,我在學習
4.使用程式碼模擬學生和老師資訊管理系統;
具體要求如下:
1:老師和學生都是人,都包含姓名和年齡屬性(要求私有)
2:老師包含特有的屬性:所講課程course;特有講課方法teach,方法的內容是: 我是xxx,今年xx歲,正在講xxx課程;
3:學生包含特有的屬性:考試分數score;特有考試方法exam,方法的內容是: 我是xxx,今年xx歲,考了xx分;
4:編寫老師和學生的測試類,分別測試老師和學生的講課和考試方法;要求建立老師和學生物件的時候,使用帶引數的構造方法建立物件;
列印效果:
我是王老師,今天38歲,正在講java課程
我是小麗,今天18歲,考了99分