Java學(xué)習(xí)(下)

三、繼承

繼承:

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

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

注意:類是單繼承的,即每個(gè)類只能有一個(gè)父類。

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

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

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

如果子類已經(jīng)將父類中的方法重寫了,調(diào)用的時(shí)候肯定是調(diào)用被重寫過(guò)的方法,那如果現(xiàn)在一定要調(diào)用父類中的方法,此時(shí)就可以通過(guò)使用super關(guān)鍵字:super.方法名(參數(shù)列表)來(lái)實(shí)現(xiàn)

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

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


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

修改項(xiàng)目測(cè)試類的代碼:

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

控制臺(tái)界面會(huì)輸出以下信息:

控制臺(tái)顯示

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

修改Dog類的代碼:

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

其他代碼不作改動(dòng),控制臺(tái)界面會(huì)輸出以下信息:

控制臺(tái)顯示

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

四、多態(tài)

多態(tài):

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

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

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

還是以Dog類和Animal類為例,修改Dog類和項(xiàng)目測(cè)試類主方法的代碼:

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

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

控制臺(tái)界面會(huì)輸出以下信息:

控制臺(tái)顯示

再次修改Dog類和項(xiàng)目測(cè)試類主方法的代碼:

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();//調(diào)用obj2的獨(dú)有的watchDoor方法
    }
}

此時(shí),obj2.watchDoor();這個(gè)地方程序會(huì)報(bào)錯(cuò):

程序報(bào)錯(cuò)

因?yàn)楦割愔胁](méi)有定義watchDoor()方法,通過(guò)父類創(chuàng)建子類對(duì)象并調(diào)用這個(gè)子類獨(dú)有的方法時(shí)就會(huì)報(bào)錯(cuò)。

抽象類:

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

  • 抽象類和抽象方法都是用abstract關(guān)鍵字來(lái)修飾
  • 當(dāng)abstract定義抽象方法時(shí),只需要聲明即可,不需要定義具體實(shí)現(xiàn)(因?yàn)槌橄箢惒⒉魂P(guān)注這些方法是如何實(shí)現(xiàn)的),即abstract 類名();//沒(méi)有方法體
  • 抽象類中既可以有普通方法,也可以有抽象方法
  • 包含抽象方法的類一定是抽象類

下面以狗類(子類)、貓類(子類)和動(dòng)物類(父類,同時(shí)也是抽象類)為例具體演示一下上面介紹的幾個(gè)概念,先定義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類中的具體實(shí)現(xiàn)
        System.out.println("狗具有吃骨頭的能力");
    }
    public void voice(){//定義voice()方法在Dog類中的具體實(shí)現(xiàn)
        System.out.println("狗“汪汪汪”地叫");
    }
}

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

修改項(xiàng)目測(cè)試類的代碼:

 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();
    }
}

控制臺(tái)界面會(huì)輸出以下信息:

控制臺(tái)顯示
接口:

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

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

注意:

  • 因?yàn)榻涌谥邪氖浅A亢统橄蠓椒ǎ远x接口的時(shí)候系統(tǒng)會(huì)自動(dòng)添加abstract關(guān)鍵字
  • 接口中的屬性均為靜態(tài)常量,因此在定義屬性的時(shí)候系統(tǒng)會(huì)自動(dòng)添加public static final修飾符
  • 接口中的方法均為抽象方法,因此在定義方法的時(shí)候系統(tǒng)會(huì)自動(dòng)添加public abstract修飾符
  • 接口是用來(lái)被繼承和被實(shí)現(xiàn)的,因此不能使用privateprotected修飾(這樣會(huì)使得接口沒(méi)有意義),一般使用public修飾

使用implements關(guān)鍵字實(shí)現(xiàn)接口。而當(dāng)類既繼承父類又實(shí)現(xiàn)接口時(shí),定義語(yǔ)法為:

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

注意:

  • 在給接口命名的時(shí)候通常在名字前面加上一個(gè)“I”
  • 繼承父類必須要在實(shí)現(xiàn)接口之前

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

先定義ISwim接口:

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

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

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

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

定義Duck類:

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

修改項(xiàng)目測(cè)試類主方法的代碼:

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();
    }
}

控制臺(tái)界面會(huì)輸出以下信息:

控制臺(tái)顯示

后記

以上的內(nèi)容是我通過(guò)看書(shū)和看視頻以及上網(wǎng)找資料歸納、總結(jié)出來(lái)的,目的在于為我今后復(fù)習(xí)Java基礎(chǔ)知識(shí)和編寫Java程序時(shí)提供可查閱的筆記,我也希望能夠給閱讀本文的Java初學(xué)者一些幫助。

參考資料

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容