1. 程式人生 > 其它 >abstract關鍵字的用法

abstract關鍵字的用法

現在我們要寫一個狗類,也要寫一個貓類:

package oop1;

public class Dog {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃飯");
    }

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

package oop1;

public class Cat {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃飯");
    }

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

可以發現,貓類和狗類中屬性和方法是一樣的,看下來程式碼幾乎是一樣的,但是我們還得寫兩遍,這就很麻煩,雖然可以複製貼上,但是當後續又有豬、猴、馬、兔呢?所以我們想要類似於一個模板一樣的東西。在Java中我們可以使用繼承。

1.什麼是繼承?

Java中將多個類中具有的相同屬性和方法抽取出來,寫到一個單獨的類中,將這個類作為父類,這裡就涉及到了繼承的概念,其它的類使用這個類去生成新的類,就叫繼承了這個類,這個類就是父類,繼承父類的其它類就作為該父類的子類

父類也叫基類、超類。子類也可叫做派生類。

我們將上述貓、狗類中的屬性和方法抽取出來,放到一個Pet類中,Dog、Cat類繼承Pet:

繼承的關鍵字:extends

語法:子類 extends 父類

Pet:

package oop1;

public class Pet {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃飯");
    }

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

Dog:繼承Pet類

public class Dog extends Pet{

}

Cat:繼承Pet類

public class Cat extends Pet{

}

如果我們再多幾個動物類,也可以繼承Pet類,這樣是不是就減少了很多的程式碼量呢?繼承的好處就是:程式碼重用

2.繼承的使用

(1)子類擁有了父類的哪些東西?

那繼承了父類有什麼用呢?我們就可以使用父類的屬性和方法了。

我們在Dog類中new一個物件,使用.來檢視一下有沒有什麼:

我們可以看到,Dog類的物件擁有了父類的全部屬性和方法。

package oop1;

public class Dog extends Pet{

    public static void main(String[] args) {
        //使用父類屬性
        Dog dog = new Dog();
        dog.name = "哈士奇";
        dog.age = 3;
        dog.color = "黑";
        System.out.println(dog.name+"\t"+dog.age+"\t"+dog.color);
        //呼叫父類方法
        dog.eat();
        dog.sleep();
    }
}

執行也是沒有問題的:

這就像兒子可以使用父親的很多東西一樣,但是兒子可以使用父親的所有東西嗎?這肯定是不可以的,那繼承的東西是否也會有限制呢?我們再來看看四個許可權修飾符的許可權表:

在學了父類、子類概念後,現在我們已經可以看明白整個表了。可以看到,private修飾的就算是同一個包下的子類都是不可訪問的,我們來實驗一下,將屬性修改成四個不同許可權修飾符修飾:

package oop1;

public class Pet {

    public String name;
    protected int age;
    String color;
    private double price;

    public void eat(){
        System.out.println("吃飯");
    }
    
    protected void walk(){
        System.out.println("散步");
    }
    
    void play(){
        System.out.println("玩耍");
    }

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

再驗證一下不同包下的子類:

驗證結果與表中一致,所以得出結論:同一包下的子類,繼承父類之後,就擁有了父類中除私有的屬性和方法;不同包下的子類,繼承父類之後,就擁有了除私有的和預設的以外的私有屬性和方法。

(2)子類能否繼承父類的構造方法?

我們說子類可以繼承父類的符合許可權的屬性和方法,那我們知道構造方法是特殊的方法,父類的構造方法能否被子類繼承呢?

構造方法是用來建立唯一的東西的,如果子類繼承了父類的構造方法,則在建立物件時就不知道建立的是父物件還是子物件,呼叫父類的構造方法,不會建立一個父物件,只是初始化父類的成員屬性和方法(因為子類繼承父類後,會獲取到父類的屬性和方法,這些屬性和方法在使用前必須先初始化,所以須先呼叫父類的構造器進行初始化)。

也不會產生父類物件,只是用了父類的構造方法而已,並不是用到構造方法就會產生物件,構造方法只是起物件初始化作用的,而不是起產生物件作用的;即只有 new 語句才會產生父類的物件。

所以,子類不會繼承父類的構造方法,但是會呼叫父類的構造方法用於初始化。

package oop1;

public class Pet {

    public Pet() {
        System.out.println("我是父類的構造方法");
    }
}

package oop1;

public class Cat extends Pet{

    public Cat() {
        System.out.println("我是子類的構造方法");
    }

    public static void main(String[] args) {
        Cat cat = new Cat();
    }

}

這裡看到雖然輸出了父類的構造方法中的輸出語句,但是隻是子類在new物件時呼叫了父類的構造方法而已。這是一個很容易混淆和繞暈自己的點。

擴充套件:

可以從結果中看出,在子類中new物件,是先輸出了父類的構造方法中的內容,再輸出了子類構造方法中的內容,這裡涉及到了:

繼承關係的初始化順序:

父類的屬性
父類的構造方法
子類的屬性
子類的構造方法

(3)能否繼承多個類?

既然繼承那麼好用,我們可不可以多繼承幾個類呢?

是不可以的,提示中寫著類不能繼承多個類,所以Java是單繼承,只能直接的繼承一個類。

(4)繼承了父類之後還能不能有自己的屬性和方法?

子類繼承了父類之後,還能不能定義自己的屬性和方法呢?

Pet:父類

package oop1;

public class Pet {

    public String name;
    public int age;
    public String color;

    public void eat() {
        System.out.println("吃飯");
    }

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

Cat:子類

package oop1;

public class Cat extends Pet{

    public double price;
    
    public void play(){
        System.out.println("貓抓老鼠");
    }

    public static void main(String[] args) {
        Cat cat = new Cat();
        //繼承父類屬性
        cat.name = "肥橘";
        //子類自定義屬性
        cat.price = 1000;
        //繼承父類方法
        cat.eat();
        //子類自定義方法
        cat.play();
    }
}

子類繼承了父類具有許可權的屬性和方法之後,也可以自定義獨有的屬性和方法。


3.總結

  • 同一包下的子類,繼承父類的除私有的以外的屬性和方法;
  • 不同包下的子類,繼承父類的除私有的和預設的以外的屬性和方法;
  • 子類不繼承父類的構造方法;
  • 單繼承,只能直接繼承一個類;
  • 繼承父類之後,子類還能自定義屬性和方法。

本人水平有限,若有錯誤,望指出~