類的繼承


概述

類的繼承是指在一個現有類的基礎上構建一個新類。

  • 新類稱作子類,現有類稱作父類。
  • 子類自動擁有父類所有可繼承的屬性和方法。

如何實現類的繼承?

聲明一個類繼承另一個類,需要使用關鍵字extends。

比如我先創建一個Person類,代碼如下:

public class Person {
    private char gender;

    public Person(){
        System.out.println("Person類無參構造方法執行");
    }

    public char getGender(){
        return gender;
    }

    public void setGender(char gender){
        this.gender = gender;
    }

    public void sleep(){
        System.out.println("要睡覺...");
    }

}

創建一個Student類,繼承Person類,代碼如下:

public class Student extends Person{
    private String name;
    int age;
    public Student(){}

    public Student(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public void intro(){
        System.out.println("我的性別是"+getGender());
    }

}

創建Student對象,程序入口代碼如下:

    public static void main(String[] args) {
        Student stu1 = new Student("大西瓜");
        stu1.age = 10;
        stu1.gender = '男';//報錯,private修飾的成員不可繼承
        stu1.setGender('男');
        stu1.intro();
        stu1.sleep();
    }

運行結果如下:

Person類無參構造方法執行
我的性別是男
要睡覺...

可以看出,

  1. Student類通過extends關鍵字繼承Person類后,雖然沒有沒有定義gender屬性和sleep()方法,卻能訪問兩個成員。
  2. private修飾的變量gender無法訪問。

這就說明,子類繼承父類時,自動擁有父類所有可繼承的成員。而被private修飾的變量gender則屬於不可繼承的成員。

  1. 創建的是Student對象,為什么Person類的無參構造會被調用?

這就要從內存創建開始說起,創建Student對象,先開辟堆內存空間。不同以往,開辟的不是Student對象的空間,而是先開辟它的父類對象的空間

再創建子類對象Student,將父類的引用賦值給新增屬性super

這就是為什么Person類構造方法被調用的原因了,

等於說是開辟了兩塊空間,一父一子兩個對象,其中子類對象中的super屬性指向父類,
我們在訪問子類中不存在、父類中存在的成員時,就相當於是通過這個屬性找到父類成員並訪問的。

繼承與權限修飾符的關系

下面通過這個表,為小伙伴們簡單講解繼承的范圍。

修飾符/訪問范圍 同一個類中 同一個包中 子類中 全局范圍
public v v v v
protected v v v
default v v
private v

由上圖,只有private修飾的類或類的成員不能被繼承。

可能細心的小伙伴會發現,Person類中的age變量沒有被修飾,修飾符應該屬於default,結果卻可以被子類訪問

這是因為,

age的修飾符屬於(default)默認修飾符,同一個包下可以訪問,而Person類和student類就在同一個包下。

繼承與類的關系

類的繼承也有限制,請注意:

  1. Java中類僅支持單繼承、不支持多繼承,即一個類只有一個直接父類。
    class A{}
    class B{}
    class C extends A,B{}//不可同時繼承多個類
  1. 多個類可以繼承一個類
class A{}
class B extends A{}
class c extends A{}//B類和C類都可以繼承A類
  1. 多層繼承是允許的,即一個類的父類可以再去繼承別的父類。
class A{}
class B extends A{}//B類繼承A類,B類是A類的子類
class C extends B{}//C類繼承B類,B類繼承A類,C類也是A類的子類、C類可以訪問B類和A類所有可繼承的成員
  1. 子類可以重寫父類的方法。
    子類中的重寫方法和父類被重寫的方法應具有相同的方法名、參數列表、返回值類型。

我們在Student類中添加父類的sleep()方法

    //與父類相同的方法名、參數列表、返回值類型。
    public void sleep(){
        System.out.println(name+"要睡覺...");
    }

程序入口,代碼如下:

    public static void main(String[] args) {
        Student stu1 = new Student("大西瓜");
        stu1.sleep();
    }

結果如下:

Person類無參構造方法執行
大西瓜要睡覺...

此時發現,JVM調用的的是子類的sleep()方法而不是父類的,這就是方法的重寫。

注意一點:子類重寫父類方法時,不能使用比父類更嚴格的訪問權限,

Person類中sleep()方法不變,子類Student中將修飾符改為比public權限更嚴格的private。

    private void sleep(){//報錯,不能使用比父類更嚴格的訪問權限
        System.out.println(name+"要睡覺...");
    }

但是如果父類的sleep()方法被private修飾,子類sleep()方法被比private權限更寬松的public修飾,則能夠實現重寫,順利運行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM