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關鍵字:指向自己的引用。