1. 程式人生 > >核心技術讀書筆記----第5章 繼承(一)

核心技術讀書筆記----第5章 繼承(一)

特殊 編譯器 父類構造函數 ack 父類 指定 引用 tsa 一句話

第5章 繼承(一)

1、super:當希望子類調用超類的方法時,使用super.方法名super不是一個對象的引用,不能將super賦值給另一個對象變量,它只是一個指示編譯器調用超類方法的特殊關鍵字。

public double getSalary(){
    double baseSalary=super.getSalary();
    return baseSalary+bonus;
}

2、子類構造器:子類構造器不能訪問超類私有域,必須利用超類構造器對這部分私有域進行初始化,並且此語句必須是子類構造器的第一句話。如果子類沒有顯示調用超類構造器,則自動調用超類默認構造器。構造函數必須出現在第一行上,註定了只能調用一個構造函數。

public Manager(String name,double salary,int year,int month,int day){
    super(name,salary,year,month,day);
    bonus=0;
}

3、this作用:1.引用隱式參數 2.調用該類其他的構造器
super作用:1.調用超類方法 2.調用超類構造器
註意:調用構造器的語句只能作為另一個構造器的第一條語句出現;構造參數既可以傳遞給本類(this)的其他構造器,也可以傳遞給超類(super)的構造器。

4、引用論壇

java規定,在執行構造函數之前必須執行父類的構造函數,直到這個類是java.lang.Object類的構造函數。
然而函數的入口是子類構造函數

,因此任何構造函數第一句必須是執行父類構造函數,如果沒有添加super關鍵字,那麽編譯器會為該構造函數第一句添加一個super()語句(你可以這麽理解,當然編譯以後並不是這樣)。如果有super關鍵字顯示的調用父類構造函數,就是用指定的那個父類構造函數,否則使用默認的無參數構造函數。也有一種情況例外,就是存在this關鍵字,調用本類其它構造函數,但是按照遞歸調用,最終還是會調用父類構造函數。
如果你繼承的父類沒有無參數構造函數,那麽你這個類第一句必須顯示的調用super關鍵字來調用父類對應的有參數構造函數,否則不能通過編譯。調用本類或者父類的構造函數,必須在構造函數的第一句,或者邏輯上的第一句。

/*
作者:mys
功能:在執行子類構造函數前必須先執行父類的構造函數
日期:2018/7/19
 */
package cn.mys;

public class Text7 {
    public static void main(String []args){
        Father father=new Father(40,"sky");
        System.out.println("father:"+father.getName()+" "+father.getAge());
        Son son=new Son(19,"mys");
        System.out.println("father:"+son.getName()+" "+son.getAge());
    }
}
//超類
class Father
{
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
    //無參構造函數
    public Father(){}
    //帶參構造函數
    public Father(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("超類構造函數");
    }
}
//子類
class Son extends Father{
    public Son(int age, String name){
        super(age,name);//調用超類構造函數初始化超類私有域
        System.out.println("子類構造函數");
    }
}

5、一個變量可以指示多種實際類型的現象稱為多態,在運行時能自動調用哪個方法的現象叫動態綁定。在Java中,不需要將方法聲明為虛擬方法,動態綁定是默認的處理方式,如果不希望一個方法具有虛擬方法的特征,則標記為final。

6、由一個公共類派生出來的所有類的集合稱為繼承層次;在繼承層次中,從某個特定的類到祖先的路徑稱為該類的繼承鏈。一個祖先類可以有多個子孫繼承鏈,Java不支持多繼承

7、置換法則:“is a ”程序中出現超類對象的任何地方都可以用子類對象替換,可以將一個子類的對象賦值給超類。
在Java中,對象變量是多態的,一個超類變量可以引用一個超類對象,也可以引用超類的任一個子類對象,不能將一個超類的引用賦值給子類對象
子類數組的引用可以轉換成超類數組的引用,而不需要采用強制轉換。註意:所有數組都要牢記創建他們的元素類型,並負責監督僅將類型兼容的引用存到數組中。

//超類變量可以引用超類的任一個子類對象
Employee e;
e=new Employee(...);
e=new Manager(...);//ok
//不能將一個超類的引用賦值給子類對象
Manager boss=new Manger(...);
Employee []staff=new Employee[3];
boss=staff[0];//變量staff[0]與boss引用同一個對象
Employee e=staff[0];//Error
//子類數組的引用可以轉換成超類數組的引用,而不需要采用強制轉換。
Manager []managers=new Manager();
Employee []staff=managers;

8、方法的調用
1)編譯器查看對象的聲明類型和方法名
2)編譯器查看調用方法時提供的參數類型
重載解析:在所有名為f的方法中存在一個與提供的參數類型完全匹配,就選擇這個方法,這個過程叫重載解析
方法的簽名:方法的名字和參數列表
3)如果是private、public、final或者構造器,那麽編譯器可以準確知道應該調用那個方法,此調用方式稱為靜態綁定
4)當程序運行時,並采用靜態綁定的方式,虛擬機一定調用與其引用對象的實際類型最合適的那個類方法。虛擬機事先為每個類創建一個方法表,其中列出所有方法的簽名和實際調用方法。如果調用super.f(),編譯器將對隱式參數超類的方法表進行搜索。

9、動態綁定無需對現存的代碼進行修改,就可以對程序進行擴展。在覆蓋一個方法時,子類方法不能低於超類方法的可見性。

10、final
1)不允許擴展的類稱為final類
2)域可以被聲明為final,但對域來說,構造對象之後就不能改變它的值
3)如果將一個類聲明為final,只有其中的方法自動成為final,而不包括域。
4)為了避免動態綁定帶來的系統開銷而使用final

11、只能在繼承層次內進行類型轉換;在將超類轉換成子類之前,應先使用instanceof進行檢查

核心技術讀書筆記----第5章 繼承(一)