1. 程式人生 > 實用技巧 >java面向物件(下)-- 類的繼承、方法的重寫、super關鍵字

java面向物件(下)-- 類的繼承、方法的重寫、super關鍵字

繼承的概念

  在現實生活中,繼承一般是指子女繼承父類的財產。在程式中,繼承描述的是事物之間的所屬關係,通過繼承可以使多種事物之間形成一種關係體系。

  例如:貓和狗都屬於動物,程式中便可以描述為貓和狗都繼承自動物,同理,波斯貓和巴釐貓繼承自貓,而沙皮狗和斑點狗繼承自狗,這些動物之間會形成一個繼承體系,如圖:

 

繼承的特性

  • 子類擁有父類非 private 的屬性、方法。

  • 子類可以擁有自己的屬性和方法,即子類可以對父類進行擴充套件。

  • 子類可以用自己的方式實現父類的方法。

  • Java 的繼承是單繼承,但是可以多重繼承,單繼承就是一個子類只能繼承一個父類,多重繼承就是,例如 A 類繼承 B 類,B 類繼承 C 類,所以按照關係就是 C 類是 B 類的父類,B 類是 A 類的父類,這是 Java 繼承區別於 C++ 繼承的一個特性。

  • 提高了類之間的耦合性(繼承的缺點,耦合度高就會造成程式碼之間的聯絡越緊密,程式碼獨立性越差)。

 

  在java中,類的繼承是指在一個現有類的繼承上去構建一個新的類,構建出來的新類被稱作子類,現有類被稱作父類,子類會自動擁有父類所有可繼承的屬性和方法。在程式中,如果想宣告一個類繼承另一個類,需要使用extends關鍵字。

 1 //定義Animal類
 2  class Animal {
 3     String name;//定義name屬性
 4        //定義動物叫的方法
 5        void shout() {
 6          System.out.println("
動物發出了叫聲!"); 7 } 8 } 9 //Dog類繼承Animal類 10 class Dog extends Animal{ 11 //定義一個定義name的方法 12 public void printName(){ 13 System.out.println("name = " + name); 14 } 15 } 16 //定義測試類 17 class Example { 18 public static void main(String[] args) { 19 Dog dog = new Dog(); //建立一個Dog類的例項物件
20 dog.name ="沙皮狗"; //為Dog類的屬性name賦值 21 dog.printName(); //呼叫Dog的printName()方法 22 dog.shout(); //呼叫Dog繼承來的shout()方法 23 } 24 }

執行結果:

  Dog通過extends關鍵字繼承了Animal類,這樣Dog便是Animal類的子類。子類雖然沒有定義name屬性和shout()方法,但是卻能訪問者兩個成員,也就是說,子類在繼承父類的時候,會自動擁有父類所有的成員。

注意:

  1.在java中,類只支援單繼承,不允許多次繼承,也就是說一個類只能有一個直接父類。

  2.多個類可以繼承一個父類,下面的情況是允許的

  3.在java中,多層繼承是可以的,即一個類的父類可以再去繼承另外的父類。

  4.在java中,子類和父類是一種相對的概念,也就是說一個類是某個類父類的同時,也可以是另一個類的子類。

方法的重寫

  在繼承關係中,子類會自動繼承父類中定義的方法,但有時在子類中需要對繼承的方法進行一些修改,即對父類的方法進行重寫。在子類中重寫的方法需要和父類被重寫的方法具有相同的方法名、引數列表以及返回值型別

  在前面的例子中,Dog從Animal類繼承了shout()方法,但是太抽象,這顯然不能描述一種具體動物的叫聲,為了解決這個問題,可以在Dog中重寫父類Animal中的shout()方法,以滿足需求。

 1 //定義Animal類
 2  class Animal {
 3        //定義動物叫的方法
 4        void shout() {
 5          System.out.println("動物發出了叫聲!");
 6     }
 7 }
 8 //Dog類繼承Animal類
 9 class Dog extends Animal{
10      //定義狗叫的方法
11     void shout(){
12         System.out.println("汪汪汪......");
13     }
14 }
15 //定義測試類
16 class Example {
17     public static void main(String[] args) {
18         Dog dog = new Dog(); //建立一個Dog類的例項物件
19         dog.shout();    //呼叫Dog的shout()方法
20     }
21  }

執行結果:

  子類對父類的方法進行重寫後,只會呼叫子類重寫的方法,並不會呼叫父類的方法

注意:子類重寫父類方法時,不能使用比父類中被重寫的方法更嚴格的訪問許可權,如父類中的方法時public,子類的方法就不能是private的。

super關鍵字

  當子類重寫父類的方法後,子類物件將無法訪問父類被重寫的方法,為了解決這個問題,在java中專門提供了一個super關鍵字用於訪問父類的成員,例如訪問父類的成員變數、成員方法和構造方法。

  1.使用super關鍵字呼叫父類的成員變數和成員方法。

  語法格式:super.成員變數

       super.成員方法([引數1,引數2····])

 1 //定義Animal類
 2  class Animal {
 3      String name = "動物";
 4        //定義動物叫的方法
 5        void shout() {
 6          System.out.println("動物發出了叫聲!");
 7     }
 8 }
 9 //Dog類繼承Animal類
10 class Dog extends Animal{
11      String name = "沙皮狗";
12      //重寫父類的shout()方法
13     void shout(){
14         super.shout();
15     }
16     //呼叫列印name的方法
17     void printName(){
18         System.out.println("name  = " +super.name);//訪問父類的成員變數
19     }
20 }
21 //定義測試類
22 class Example {
23     public static void main(String[] args) {
24         Dog dog = new Dog(); //建立一個Dog類的例項物件
25         dog.shout();    //呼叫Dog物件重寫的shout()方法
26         dog.printName();//呼叫Dog物件的printName()方法
27     }
28  }

執行結果:

  在子類Dog的shout()方法使用"super.shout()"呼叫了父類被重寫的方法,在printName()方法中使用''super.name''訪問的是父類的成員變數。

  2.使用super關鍵字呼叫父類的構造方法。

    語法格式:super([引數1,引數2·····])

 1 //定義Animal類
 2  class Animal {
 3     public Animal(String name) {
 4         System.out.println("我是一隻"+name);
 5     }
 6 }
 7 //Dog類繼承Animal類
 8 class Dog extends Animal{
 9     public Dog() {
10         super("沙皮狗");
11     }
12 }
13 //定義測試類
14 class Example {
15     public static void main(String[] args) {
16         Dog dog = new Dog(); //例項化Dog物件
17 
18     }
19  }

執行結果:

  在例項化Dog物件時一定會呼叫Dog的構造方法,Dog類的構造方法被呼叫時父類的構造方法也被呼叫了。需要注意的是,通過super呼叫父類的構造方法的程式碼必須位於子類構造方法的第一行,並且只能出現一次。

  在子類的構造方法中通過super指定呼叫父類的哪個構造方法,如果沒有指定,在例項化類物件時,會自動呼叫父類無參的構造方法,如果沒特殊要求,儘量在類中定義一個無參的構造方法,避免被繼承時出現錯誤。

  

super 與 this 關鍵字

super關鍵字:我們可以通過super關鍵字來實現對父類成員的訪問,用來引用當前物件的父類。

this關鍵字:指向自己的引用。