Java筆記04:面向對象基礎

繼承

Java使用extends關鍵字來實現繼承:

class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

class Student extends Person {
    // 不要重複name和age字段/方法,
    // 只需要定義新增score字段/方法:
    private int score;

    public int getScore() {...}
    public void setScore(int score) {...}
}

通過繼承,子類Student獲得了父類Person已有的字段與方法,節省了重複編寫代碼的時間。
Java中所有的類都繼承自Object這個類,除了它自身。
private關鍵字修飾的字段,只能在類中被訪問,子類也無法訪問,爲了讓子類也能使用父類的字段,要把修飾符改成protected

多態

在上一篇中講到構造方法時有提到過方法簽名的概念,當一個子類與其父類有着相同的方法簽名的方法(修飾符、參數、返回值都相同)時,稱之爲覆寫
注意上篇中講的重載,並不要求方法簽名完全相同,編譯器也是根據這個將重載的方法區分開來。覆寫則在運行期間動態決定調用的方法,以實現多態。

class Animal {
    public void sound {...}
}
class Cat {
    @Override
    public void sound {
        System.out.println("meow")
    }
}

使用@Override可以讓編譯器幫我們檢查覆寫是否正確。

final修飾符:

  • final修飾的字段必須在聲明是初始化並且無法被修改,也就是常量
  • final修飾的方法不能被子類覆寫
  • final修飾的類不能被繼承

抽象類

有時候,如果父類的方法沒有實際意義,能不能不寫呢?

class Person {
    public void run(); // Compile Error!
}

上述代碼會報錯。
如果一個方法只定義方法簽名,沒有實質內容,可以用abstract修飾符把它定義成抽象方法,包含抽象方法的類也必須被聲明爲抽象類(abstract class)。

abstract class Person {
    public abstract void run();
}

抽象類不能被實例化,方法也是空的,這個類用來幹什麼的呢?抽象類本身被設計成只能用於被繼承,因此,抽象類可以強迫子類實現其定義的抽象方法,否則編譯會報錯。因此,抽象方法實際上相當於定義了“規範”。
對於抽象類的子類,我們可以用抽象類型去引用它的子類型:

Person s = new Student();
Person t = new Teacher();
s.run();
t.run();

我們可以直接調用它的方法而不必關心具體類型,可以確信抽象類的子類是一定實現了這些方法的。

接口

有一種極端的“抽象類”,它只包含抽象方法,這種東西可以寫成接口

interface Person {
    void run();
    String getName();
}

由於接口肯定都是抽象方法了,所以沒必要用abstract修飾符。事實上它的方法都默認是public abstract。聲明接口用interface
某個類要去實現接口,要用implements關鍵字。

class Dog implements Animal {
    ...
}
Java中一個類只能繼承自一個父類,通過接口則可以實現多重繼承,一個類可以實現多個接口。(Python支持多重繼承)

接口中還可以有一種default修飾符修飾的默認方法,這種方法可以有一個默認實現,具體實現的類可以不必覆寫它。

有時候可能兩個人都實現了一個名爲Person的類,同時還想引用對方的類來使用。對於這種命名衝突的情況應該怎麼辦呢?
Java使用包package來解決命名衝突。在定義一個類時,把它的包名寫在第一行。
下面是用IDE編寫程序時自動創建的代碼部分:

package com.company;

public class Main {
    public static void main(String[] args) {

    }
}

與下面某人編寫的同名Main類:

package harry;

public class Main {
    public static void main(String[] args) {

    }
}

雖然這兩個類同名了,但在運行時,這兩個類會使用完整類名,它們的完整名分別是com.company.Mainharry.Main
有時候要使用一個包中的類,一種寫法是直接寫完整類名,但那樣就有點麻煩,我們可以和Python中一樣使用import語句。
例如要使用 java.util包中的ArrayList

import java.util.ArrayList;

public class SingleImport {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
    }
}

這個包裏還含有很多類,可以使用星號*

import java.util.*;

這樣表示把這個包裏所有類都導入。

掃碼關注:
公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章