1.繼承比較好理解,多各類有相同的屬性和行爲的時候,將這些內容抽取到一個單獨的類中就可以簡化成繼承關係了
1)表達式:class 子類名 extends 父類名 {}
2)好處:a.提高了代碼的複用性,b.提高了代碼的維護性,c.讓類與類產生關係,是多態的前提。
3)Java只支持單繼承,不支持多繼承,但可以多層繼承。
4)子類只能繼承所有父類的非私有成員,不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類的構造方法。
5)繼承中成員變量的關係:
當子類中的成員變量和父類中的成員變量名稱一樣時,在子類方法中訪問一個變量的查找順序:
a:在子類方法的局部範圍找,有就使用
b:在子類的成員範圍找,有就使用
c:在父類的成員範圍找,有就使用(肯定不能訪問到父類局部範圍)
d:如果還找不到,就報錯。
2.this和super的區別?
this代表本類對應的引用。
super代表父類存儲空間的標識(可以理解爲父類引用,可以操作父類的成員)
用法上
1)調用成員變量
this.成員變量 調用本類的成員變量
super.成員變量 調用父類的成員變量
2)調用構造方法
this(...) 調用本類的構造方法
super(...) 調用父類的構造方法
3)調用成員方法
this.成員方法 調用本類的成員方法
super.成員方法 調用父類的成員方法
注意:super(…)或者this(….)必須出現在第一條語句上,否則,就會有父類數據的多次初始化
3.繼承中構造方法的關係
子類中所有的構造方法默認都會訪問父類中空參數的構造方法
因爲子類會繼承父類中的數據,可能還會使用父類的數據。
所以,子類初始化之前,一定要先完成父類數據的初始化。
注意:子類每一個構造方法的第一條語句默認都是:super();
4.執行流程,判斷結果
class Fu {
static {
System.out.println("靜態代碼塊Fu");
}
{
System.out.println("構造代碼塊Fu");
}
public Fu() {
System.out.println("構造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("靜態代碼塊Zi");
}
{
System.out.println("構造代碼塊Zi");
}
public Zi() {
System.out.println("構造方法Zi");
}
}
class ExtendsTest2 {
public static void main(String[] args) {
Zi z = new Zi();
}
}
執行結果是:
靜態代碼塊Fu
靜態代碼塊Zi
構造代碼塊Fu
構造方法Fu
構造代碼塊Zi
構造方法Zi
1)一個類的靜態代碼塊,構造代碼塊,構造方法的執行流程
靜態代碼塊 > 構造代碼塊 > 構造方法
2)靜態的內容是隨着類的加載而加載
靜態代碼塊的內容會優先執行
3)子類初始化之前先會進行父類的初始化
5.方法重寫
子類中出現了和父類中一模一樣的方法聲明,也被稱爲方法覆蓋,方法複寫。
6.方法重寫的注意事項
1)父類中私有方法不能被重寫
2)子類重寫父類方法時,訪問權限不能更低
3)父類靜態方法,子類也必須通過靜態方法進行重寫。(其實這個算不上方法重寫,但是現象確實如此,至於爲什麼算不上方法重寫,多態中我會講解)
7.方法重載能改變返回值類型嗎?
方法重載能改變返回值類型,因爲它和返回值類型無關。
Override:方法重寫
Overload:方法重載
8.final關鍵字是最終的意思,可以修飾類,成員變量,成員方法。
特點:
1)final可以修飾類,該類不能被繼承。
2)final可以修飾方法,該方法不能被重寫。(覆蓋,複寫)
3)final可以修飾變量,該變量不能被重新賦值。因爲這個變量其實常量。
自定義常量 final int x = 10;
9.final修飾局部變量
1) 在方法內部,該變量不可以被改變
2) 在方法聲明上:
基本類型,是值不能被改變
引用類型,是地址值不能被改變
10.多態
某一個事物,在不同時刻表現出來的不同狀態。
多態前提和體現
1)有繼承關係
2) 有方法重寫
3) 有父類引用指向子類對象
11.多態中的成員訪問特點:
1)成員變量
編譯看左邊,運行看左邊。
2)構造方法
創建子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。
3)成員方法
編譯看左邊,運行看右邊。
由於成員方法存在方法重寫,所以它運行看右邊。
4)靜態方法
編譯看左邊,運行看左邊。
(靜態和類相關,算不上重寫,所以,訪問還是左邊的)
12.多態的好處
1)提高了程序的維護性(由繼承保證)
2)提高了程序的擴展性(由多態保證)
13.多態的弊端: 不能使用子類的特有功能。
所以爲了引用子類的特有功能,把父類的引用強制轉換爲子類的引用
對象間的轉型問題:
向上轉型:
Fu f = new Zi();
向下轉型:
Zi z = (Zi)f; //要求該f必須是能夠轉換爲Zi的。
14.自己在默寫代碼時出現的錯誤
/*
多態練習:貓狗案例
*/
class Animal
{
public void eat(){
System.out.println("進食");
}
}
class Cat extends Animal
{
public void eat(){
System.out.println("吃魚<?)))><<");
}
public void playGame(){
System.out.println("玩毛線,抓蝴蝶");
}
}
class Dog extends Animal
{
public void eat(){
System.out.println("吃骨頭@==@");
}
public void lookDoor(){
System.out.println("有人來了,汪汪~~");
}
}
class PolymorphismTest // polymorphism:多態性
{
public static void main(String[] args){ /*第一次編譯又忘了打這一句,看來以後防止自己再忘,寫代碼是首先寫主方法*/
Animal a = new Cat();
a.eat();
Cat b = (Cat)a;
b.eat();
b.playGame(); /*a.playGame();// 錯誤:變量a的類型爲Animal*/
System.out.println("---------------");
a = new Dog();
a.eat();
Dog c = (Dog)a;
c.eat();
c.lookDoor();
}
}