1. 程式人生 > >Java 從入門到進階之路(十)

Java 從入門到進階之路(十)

之前的文章我們介紹了一下 Java 中的引用型陣列型別,接下來我們再來看一下 Java 中的繼承。

繼承的概念

繼承是java面向物件程式設計技術的一塊基石,因為它允許建立分等級層次的類。

繼承就是子類繼承父類的特徵和行為,使得子類物件(例項)具有父類的例項域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。

在日常生活中,我們會養些貓和狗,從程式的角度講貓和狗都屬於物件,那麼我們就可以根據其特性來定義,如下:

 1 class Dog extends Animal {
 2     String name;
 3     String color;
 4     int age;
 5 
 6     void run() {
 7         System.out.println("我可以跑");
 8     }
 9 
10     void lookDoor() {
11         System.out.println("我可以看門");
12     }
13 }
14 
15 class Cat {
16     String name;
17     String color;
18     int age;
19 
20     void run() {
21         System.out.println("我可以跑");
22     }
23 
24     void catchMouse() {
25         System.out.println("我可以抓老鼠");
26     }
27 }

我們在定義 Dog 和 Cat 類的時候發現它們絕大部分屬性和方法是相同的。那這樣的話我們再定義其他動物的時候同樣會出現這種氣礦,這就造成了大量程式碼的重複,造成程式臃腫,不易維護。

我們可以這樣解決上面的問題,將 Dog 和 Cat 類裡相同的屬性和方法寫到一個父類裡,自己特有的方法在自己的類裡完成,這樣就可以有效的解決上面的問題,其實這就是 Java 類的繼承,如下:

 1 public class HelloWorld {
 2     public static void main(String[] args) {
 3         Dog dog = new Dog();
 4         dog.run(); // 我可以跑
 5         dog.lookDoor(); // 我可以看門
 6 
 7         Cat cat = new Cat();
 8         cat.run(); // 我可以跑
 9         cat.catchMouse(); // 我可以抓老鼠
10     }
11 }
12 
13 class Animal{
14     String name;
15     String color;
16     int age;
17 
18     void run() {
19         System.out.println("我可以跑");
20     }
21 }
22 
23 class Dog extends Animal {
24     void lookDoor() {
25         System.out.println("我可以看門");
26     }
27 }
28 
29 class Cat extends Animal {
30     void catchMouse() {
31         System.out.println("我可以抓老鼠");
32     }
33 }

在上面的程式碼中,我們定義類一個 Animal 類,裡面定義了 Dog 和 Cat 類中相同的屬性和方法,然後我們在定義 Dog 和 Cat 類的時候通過  extends Animal 的方式來繼承 Animal 類,當我們繼承 Animal 類的時候,Animal 類中的屬性和方法就會被一併繼承過來,這樣我們在宣告 Dog 和 Cat 類的時候便可以呼叫從 Animal 類及成果來的屬性和方法,這就是繼承。

繼承:

1、目的:避免程式碼重複,有利於程式碼的重用

2、通過 extends 實現繼承

3、父類:所有子類所用共有的屬性和方法;子類:子類所特有的屬性和方法

4、子類繼承父類後,子類具有 子類+父類 的屬性和方法

5、一個父類可以有多個子類,一個子類只能有一個父類-----單一繼承

6、繼承具有傳遞性

7、Java 規定:構造子類之前必須先構造父類,子類構造中若沒有呼叫父類的構造,則預設super(),若自己調了,則不再預設提供。

在上面的5,6條我們可以看出,在寫程式時,我們不能這樣  class Dog extends Cat extends Animal 的形式來實現繼承,這樣會出現編譯錯誤,但是我們可以通過  class Cat extends Animal  class Dog extends Cat 的形式來逐層進行繼承。

 

在上面的程式碼中我們已經瞭解了 Java 的繼承,接下來我們在結合之前說到的構造方法來介紹一下 super

 1 public class HelloWorld {
 2     public static void main(String[] args) {
 3         Dog dog = new Dog();
 4         dog.run(); // 我可以跑
 5         dog.lookDoor(); // 我可以看門
 6         dog.name = "旺財";
 7         dog.color = "黃色";
 8         dog.age = 8;
 9         System.out.println("我叫" + dog.name + ",今年" + dog.age + ",是" + dog.color + "的"); // 我叫旺財,今年8,是黃色的
10 
11         Cat cat = new Cat("咪咪", "白色", 5);
12         cat.run(); // 我可以跑
13         cat.catchMouse(); // 我可以抓老鼠
14         System.out.println("我叫" + cat.name + ",今年" + cat.age + ",是" + cat.color + "的"); // 我叫咪咪,今年5,是白色的
15     }
16 }
17 
18 class Animal {
19     String name;
20     String color;
21     int age;
22 
23     Animal() {
24 
25     }
26 
27     Animal(String name, String color, int age) {
28         this.name = name;
29         this.color = color;
30         this.age = age;
31     }
32 
33     void run() {
34         System.out.println("我可以跑");
35     }
36 }
37 
38 class Dog extends Animal {
39     Dog() {
40         super();
41     }
42 
43     void lookDoor() {
44         System.out.println("我可以看門");
45     }
46 }
47 
48 class Cat extends Animal {
49     Cat(String name, String color, int age) {
50         super(name, color, age);
51     }
52 
53     void catchMouse() {
54         System.out.println("我可以抓老鼠");
55     }
56 }

在上面的程式碼中,我們在父類 Animal 類中分別定義了一個無參構造和一個有參構造,在子類 Dog 中定義了一個無參構造,在子類 Cat 中定義類一個有參構造,我們發現,在子類的構造方法中我們添加了一個 super() 的方法,通過這種方法我們就可以繼承來自父類的構造方法,從而在例項化我們的子類的時候初始化我們想要的引數,在繼承父類的有參構造的時候需要將父類有參構造的引數傳遞進來。

接下來我們來看下面的程式碼:

 1 public class HelloWorld {
 2     public static void main(String[] args) {
 3         Dog dog1 = new Dog();
 4         Dog dog2 = new Animal(); // 編譯錯誤
 5         Animal animal1 = new Animal();
 6         animal1.run(); // 我可以跑
 7         animal1.lookDoor(); // 編譯錯誤
 8         Animal animal2 = new Dog();
 9         animal2.run(); // 我可以跑
10         animal1.lookDoor(); // 編譯錯誤
11     }
12 }
13 
14 class Animal {
15     String name;
16     String color;
17     int age;
18 
19     Animal() {
20 
21     }
22 
23     Animal(String name, String color, int age) {
24         this.name = name;
25         this.color = color;
26         this.age = age;
27     }
28 
29     void run() {
30         System.out.println("我可以跑");
31     }
32 }
33 
34 class Dog extends Animal {
35     Dog() {
36         super();
37     }
38 
39     void lookDoor() {
40         System.out.println("我可以看門");
41     }
42 }

在上面的程式碼中,我們如果通過 new Dog() 來建立一個 Dog 物件是完全沒有問題的,通過 new Animal() 來建立一個 Animal 物件也是沒有問題的,但是通過 new Animal() 來建立一個 Dog 物件會編譯錯誤,通過 new Dog() 來建立一個 Animal 物件也是沒有問題的,我們可以這樣理解,new 類名() 所指向的類必須是本類或父類,不能是子類,即等號左側的型別必須大於或等於等號右側的 new 出來的類。當大於時我們稱之為向上造型。向上造型後  子類 將不再具備其自己定義的方法,只有父類的方法。

&n