Java學習(下)

三、繼承

繼承:

繼承是類與類的一種關系,是一種“is a”的關系。比如說,狗是一種動物(dog is an animal),汽車是一種交通工具(car is a vehicle),在這里動物和交通工具就稱為父類(基類),狗和汽車就稱為子類(派生類)。就像日常生活中我們所說的繼承一樣,兒子會繼承父親的一些相貌上或者性格上的特點,還會耳濡目染、有樣學樣地繼承父親的一些行為方式;而在Java中,子類則會繼承父類所有的屬性和方法(當然private修飾的屬性和方法不可以繼承哦)。
繼承的關鍵字為extends具體定義語法為:

 [權限修飾符] class 類名 extends 父父類名{
    //定義或修改屬性
    //定義或重寫方法
}

注意:類是單繼承的,即每個類只能有一個父類

方法的重寫與方法的重載:

上面說過子類可以繼承父類的方法,但如果父類中的方法不夠完善或者不能滿足子類的要求,這時候子類就可以修改父類的方法,拓展功能或者重新定義,這就是方法的重寫。
在同一個類中,我們可以定義一些名稱相同的方法,但這些方法的參數或者返回值類型卻不同。在調用方法時,雖然這些方法都是同名的,但Java會根據不同的參數列表來選擇正確的方法進行調用,這就是方法的重載。
方法的重寫和重載從字面上來看只有一字之差,但是本質上卻有很大的區(qū)別,以下是需要注意的幾點:

  • 子類中重寫的方法與父類中的方法有完全相同返回值類型方法名參數個數以及參數類型,只是方法體不同
  • 重載的方法必須具有不同的參數列表,即不同的參數類型或者不同的參數個數或者不同的參數順序,因此方法體也就不同了。除此之外,權限修飾符和返回值類型也可以不同,但方法名必須要相同
  • 方法的重寫和重載都可以改變權限修飾符,但都只能將范圍擴大(關于權限修飾符的作用范圍上文有介紹)
  • 一般來說,重載方法時,方法之間需要存在一定的聯(lián)系,例如功能相似,因為這樣才能使方法的重載有意義,并且提高程序的可讀性
super關鍵字:

如果子類已經將父類中的方法重寫了,調用的時候肯定是調用被重寫過的方法,那如果現在一定要調用父類中的方法,此時就可以通過使用super關鍵字:super.方法名(參數列表)來實現

下面以狗類(子類)和動物類(父類)為例具體演示一下上面介紹的幾個概念,先定義Dog類和Animal類:

package com.project;
public class Animal{//定義Animal類
    int legs = 2;//定義legs屬性
    public void eat(){//定義eat方法 
        System.out.println("動物具有吃東西的能力");
}  


package com.project;
public class Dog extends Animal{//定義Dog類
}

修改項目測試類的代碼:

    public class Test {
    public static void main(String[] args) {
        Dog obj = new Dog();//創(chuàng)建Dog類對象obj
        System.out.println(obj.legs);//輸出obj的legs屬性值
        obj.eat();//調用obj的eat()方法
    }
}

控制臺界面會輸出以下信息:

控制臺顯示

說明子類可以繼承父類的屬性和方法。

修改Dog類的代碼:

  public class Dog extends Animal{
    int legs = 4;
    public void eat(){//重寫eat()方法 
        super.eat();//用super關鍵字調用Animal類中的eat()方法
        System.out.println("狗具有吃骨頭的能力");
      }
  }

其他代碼不作改動,控制臺界面會輸出以下信息:

控制臺顯示

說明子類可以修改父類的屬性和重寫父類的方法。

四、多態(tài)

多態(tài):

多態(tài),從字面上理解就是多種形態(tài),Java中指的是對象的多種形態(tài)。

多態(tài)分為兩種:

  • 引用多態(tài):父類的引用既可以指向本類的對象,也可以引用子類的對象
  • 方法多態(tài):當通過父類創(chuàng)建本類對象時,調用的方法為本類的方法;創(chuàng)建子類對象時,調用的方法為子類繼承的方法或重寫的方法(即不能調用子類獨有的方法)

還是以Dog類和Animal類為例,修改Dog類和項目測試類主方法的代碼:

public class Dog extends Animal{
    public void eat(){
        System.out.println("狗具有吃骨頭的能力");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal obj1 = new Animal();//通過Animal類創(chuàng)建Animal類對象obj1
        Animal obj2 = new Dog();//通過Animal類創(chuàng)建Dog類對象obj2(通過構造方法可以區(qū)別創(chuàng)建的是哪類對象)
        obj1.eat();//調用obj1的eat()方法
        obj2.eat();//調用obj2重寫的eat()方法
    }
}

控制臺界面會輸出以下信息:

控制臺顯示

再次修改Dog類和項目測試類主方法的代碼:

public class Dog extends Animal{
    public void eat(){
        System.out.println("狗具有吃骨頭的能力");
    }
    public void watchDoor(){//定義watchDoor方法
        System.out.println("狗具有看門的能力");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal obj1 = new Animal();
        Animal obj2 = new Dog();
        obj1.eat();
        obj2.eat();
        obj2.watchDoor();//調用obj2的獨有的watchDoor方法
    }
}

此時,obj2.watchDoor();這個地方程序會報錯:

程序報錯

因為父類中并沒有定義watchDoor()方法,通過父類創(chuàng)建子類對象并調用這個子類獨有的方法時就會報錯。

抽象類:

抽象類只是規(guī)定子類必須擁有的方法,但并不規(guī)定這些方法是如何實現的。因此,可以從多個具有相同特征的類中抽象出一個抽象類,這個抽象類作為子類的模版,從而避免子類設計的隨意性。需要注意的是:

  • 抽象類和抽象方法都是用abstract關鍵字來修飾
  • abstract定義抽象方法時,只需要聲明即可,不需要定義具體實現(因為抽象類并不關注這些方法是如何實現的),即abstract 類名();//沒有方法體
  • 抽象類中既可以有普通方法,也可以有抽象方法
  • 包含抽象方法的類一定是抽象類

下面以狗類(子類)、貓類(子類)和動物類(父類,同時也是抽象類)為例具體演示一下上面介紹的幾個概念,先定義Dog類、Cat類和Animal類:

public abstract class Animal{//定義Animal抽象類
    public abstract void eat();//定義eat抽象方法
    public abstract void voice();//定義voice抽象方法 
}  

public class Dog extends Animal{
    public void eat(){//定義eat()方法在Dog類中的具體實現
        System.out.println("狗具有吃骨頭的能力");
    }
    public void voice(){//定義voice()方法在Dog類中的具體實現
        System.out.println("狗“汪汪汪”地叫");
    }
}

public class Cat extends Animal{
    public void eat(){//定義eat()方法在Cat類中的具體實現
        System.out.println("貓具有吃魚的能力");
    }
    public void voice(){//定義voice()方法在Cat類中的具體實現
        System.out.println("貓“喵喵喵”地叫");
    }
}

修改項目測試類的代碼:

 public class Test {
    public static void main(String[] args) {
        Dog obj1 = new Dog();
        Cat obj2 = new Cat();
        obj1.eat();
        obj1.voice();
        obj2.eat();
        obj2.voice();
    }
}

控制臺界面會輸出以下信息:

控制臺顯示
接口:

接口定義的是某一批類所共同遵守的規(guī)范,既不關心這些類中的數據,也不關心這些類中方法的具體實現,只規(guī)定這些類中必須包含的方法(這一點與抽象類很相似)。
定義接口的關鍵字為interface。接口不同于類,它可以繼承多個父接口。具體的定義語法為:

[權限修飾符] [abstract] interface 接口名 [extends 父接口1, 父接口2, ...]{
    //定義一個或多個常量
    //定義一個或多個抽象方法
}

注意:

  • 因為接口中包含的是常量和抽象方法,所以定義接口的時候系統(tǒng)會自動添加abstract關鍵字
  • 接口中的屬性均為靜態(tài)常量,因此在定義屬性的時候系統(tǒng)會自動添加public static final修飾符
  • 接口中的方法均為抽象方法,因此在定義方法的時候系統(tǒng)會自動添加public abstract修飾符
  • 接口是用來被繼承和被實現的,因此不能使用privateprotected修飾(這樣會使得接口沒有意義),一般使用public修飾

使用implements關鍵字實現接口。而當類既繼承父類又實現接口時,定義語法為:

[權限修飾符] class 類名 extends 父類 implements 接口1, 接口2, ...{//一個類可以實現多個接口
    //如果繼承了抽象類,要包含繼承的抽象方法;此外還要包含接口的抽象方法
}

注意:

  • 在給接口命名的時候通常在名字前面加上一個“I”
  • 繼承父類必須要在實現接口之前

還是以狗類、貓類為例,現在要他們都繼承哺乳動物類。狗和貓都有吃東西和叫的能力,但狗能游泳而貓卻不能。在大自然中,鴨子也是會游泳的,但很明顯,鴨子并不屬于哺乳動物,即不能繼承哺乳動物類。因此要想描述狗和鴨子都具有游泳的能力,就要用到接口。

先定義ISwim接口:

package com.project;
public interface ISwim{
    public void swim();
}

定義Mammal類(定義的代碼與Animal類一樣,只是類名不同),修改Dog類和Cat類的代碼,:

public class Dog extends Mammal implements ISwim{//實現ISwim接口
    public void eat(){
        System.out.println("狗具有吃骨頭的能力");
    }
    public void voice(){
        System.out.println("狗“汪汪汪”地叫");
    }
    public void swim(){//定義swim()方法在Dog類中的具體實現
        System.out.println("狗具有游泳的能力");
    }
}

public class Cat extends Mammal{
    public void eat(){
        System.out.println("貓具有吃魚的能力");
    }
    public void voice(){
        System.out.println("貓“喵喵喵”地叫");
    }
}

定義Duck類:

public class Duck implements ISwim{//實現ISwim接口
    public void swim(){//定義swim()方法在Duck類中的具體實現
        System.out.println("鴨子具有游泳的能力");
    }
}

修改項目測試類主方法的代碼:

public class Test {
    public static void main(String[] args) {
        Dog obj1 = new Dog();
        Cat obj2 = new Cat();
        Duck obj3 = new Duck();
        obj1.eat();
        obj1.voice();
        obj1.swim();
        obj2.eat();
        obj2.voice();
        obj3.swim();
    }
}

控制臺界面會輸出以下信息:

控制臺顯示

后記

以上的內容是我通過看書和看視頻以及上網找資料歸納、總結出來的,目的在于為我今后復習Java基礎知識和編寫Java程序時提供可查閱的筆記,我也希望能夠給閱讀本文的Java初學者一些幫助。

參考資料

《Java——從入門到精通》
慕課網(IMOOC)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文出自 Eddy Wiki ,轉載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,228評論 0 5
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,779評論 18 399
  • 轉自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,618評論 3 93
  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,691評論 0 11
  • 感恩昨晚開車回家后有一個好車位;感恩妹夫帶好吃的給我們;感恩老公中午做的美餐;感恩孩子們;感恩昨天爸爸媽媽的招待;...
    深山_132f閱讀 87評論 2 1