JAVA繼承


先看以下代碼

class Student {
    String name;
    int age;
    void study() {
        System.out.println("good study");
    }
}

class Worker {
    String name;
    int age;
    void work() {
        System.out.println("good work");
    }
}

 

以上代碼中,有兩個類,各自己含有兩個成員變量和一個成員方法。

其中,“String name;int age;”這兩個變量,是兩個類中所具備的共性的描述。

那么有沒有辦法,將共性的描述抽取單獨封裝,又可以讓兩個類所共用呢?答案當然是肯定的,這就用到JAVA類的一個特性——繼承(extends)。

 

使用繼承后,只要將學生和工人的共性供述提取出來,單獨描述。然后讓學生和工人類與這個單獨描述的共性類有關系,就可以了。

代碼如下:

class People {            //共性描述,即父類、超類、基類
    String name;
    int age;
}
    
class Student extends People{        //子類,繼承父類
    void study() {
        System.out.println("good study");
    }
}

class Worker extends People{
    void work() {
        System.out.println("good work");
    }

 

繼承的作用:
1、提高了代碼的復用性
2、使類與類之間產生了關系,有了這個關系,才有多態的特性。

 

注:
不要為了獲取其它類的功能,簡化代碼而繼承。必須是類與類之間有所屬關系,所屬關系是is a
父類是由子類不斷抽取而來的。

如以下代碼,

class A{
  demo1(){}
  demo2(){}
}
class B extends A{
  demo1(){} 
  demo3(){}
}

以下繼承方式就是錯誤的

class A{
    demo1(){}
    demo2(){}
}
class B extends A{
    //demo1(){}        //為了簡化A中的demo1方法而去繼承,是錯誤的。繼承的結果是B中有了demo1和demo2,可是B中沒有demo2
    demo3(){}
}

以下是正確的繼承方式

class C{          //將classA和classB的共性抽取,單獨成立一個新的類
    demo1(){}    
}
class A extends C{
    demo2(){}
}
class B extends C{
    demo3(){}
}

 

先有父類,再有子類。

 

 JAVA中只繼承單繼承,不支持多繼承。因為多繼承容易帶來安全隱患,當多個父類中定義了相同的功能,但功能內容不同時,子類對象就不確定要運行哪一個功能。

但是JAVA保留了這種機制,用另一種體現形式來完成多繼承——多實現。

JAVA支持多層繼承。也就是一個繼承體系。如何使用繼承體系中的功能呢?

先查問體系父類的描述,因為父類中定義的是該體系中的功性功能。通過了解該共性功能,就可以了解該體系的基本功能。那么這個體系也就可以基本使用了。

在具體調用時,要創建最子類的對象。原因一,父類有可能不能創建對象;原因二,創建子為對象可以使用更多的功能,包括基本的和特有的。

 

簡單一句話:查閱父類功能,創建子類對象使用功能。

 

示例1、

public class ExtendsDemo1 {

    public static void main(String[] args) {
        Zi z = new Zi();
        System.out.println(z.num1 + "..." + z.num2);

    }

}

class Fu { // 父類。
    int num1 = 1;

}

class Zi extends Fu { // 子類。繼承了父類,所以父類的num1可以直接使用。
    int num2 = 2;

}

輸出:

1...2

 

示例1、

如子父成員變量同名,且非私有,子類訪問子類變量要用this,子類訪問父類變量要用super

public class extendsdemo {

    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

class Fu {
    int num = 1;

}

class Zi extends Fu { // 子父類有相同的變量。
    int num = 2; // 和父類變量名相同

    void show() {
        System.out.println(this.num); // this代表本類對象的引用
        System.out.println(super.num); // super代表父類對象的引用
    }

}

 

示例2:

子父類出現完全一樣的函數時,當子類對象調用子類函數,會運行子類的內容。
如同父類函數被覆蓋一樣,這種情況是函數的另一個特性————重寫(覆蓋)

當子類繼承父類,沿襲了父類的功能到子類中,但子類雖具備該功能,但是功能的內容卻和父類不一樣。這時,就沒有必要在子類中重新定義該功能,而只要使用覆蓋特性,保留父類的功能定義即可。


此時父類的方法還存在於內存中,只是沒有運行。

public class ExtendsDemo {

    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

class Fu {
    void show() { //
        System.out.println("show fu");
    }
}

class Zi extends Fu {
    void show() {     // 和父類方法同名,一模一樣,覆蓋。
        System.out.println("show zi");
    }
}

輸出:

show zi

 

注:

子類覆蓋父類時,必須保證子類權限大於等於父類權限,才可覆蓋,否則編譯失敗。

靜態只能覆蓋靜態

 

以下代碼中,子父類中的雖然有相同的show方法,但父類中的show方法是private修飾的,也就是子類完全不知道父類中有這個方法,也就談不上覆蓋了。

class Fu {
    private void show() { 
        System.out.println("show fu");
    }
}

class Zi extends Fu {
    void show() {     //這不叫覆蓋。
        System.out.println("show zi");
    }
}

 

 

 

重載:只看同名函數的參數列表

重寫:子父類方法要一模一樣

 


免責聲明!

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



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