1. 程式人生 > 實用技巧 >學習java的第三週

學習java的第三週

面對物件程式設計(二)

繼承

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(父類)

  • 利用extends關鍵字來實現繼承,可以不用再Student中寫Person相同的部分。
  • 但是上述程式碼有個問題,子類無法訪問父類的private欄位或者private方法,但是可以把private改為protected,用protected修飾的欄位可以被子類訪問。

關鍵字super

class Student extends Person {
    public String hello() {
        return "Hello, " + super.name;
    }
}
  • 子類引用父類的欄位時,可以用super.fieldName
    this.fieldNamefieldName的形式來引用。
  • 某些時候就必須使用super,如果父類沒有預設的構造方法,子類就必須顯式呼叫super()

向上轉型與向下轉型

向上轉型

  • 如果一個引用變數的型別是Student,那麼它可以指向一個Student型別的例項:
    Student s = new Student();
  • 如果一個引用型別的變數是Person,那麼它可以指向一個Person型別的例項:
    Person p = new Person();
  • 把一個子類型別安全地變為父類型別的賦值,被稱為向上轉型
Student s = new Student();
Person p = s; // upcasting, ok
Object o1 = p; // upcasting, ok
Object o2 = s; // upcasting, ok

繼承樹是Student > Person > Object,所以,可以把Student型別轉型為Person,或者更高層次的Object

向下轉型

  • 向上轉型相反,如果把一個父類型別強制轉型為子類型別,就是向下轉型
Person p1 = new Student(); // upcasting, ok
Person p2 = new Person();
Student s1 = (Student) p1; // ok
Student s2 = (Student) p2; // runtime error! ClassCastException!

多型

多型是指,針對某個型別的方法呼叫,其真正執行的方法取決於執行時期實際型別的方法。

public class Main {
    public static void main(String[] args) {
        // 給一個有普通收入、工資收入和享受國務院特殊津貼的小夥伴算稅:
        Income[] incomes = new Income[] {
            new Income(3000),
            new Salary(7500),
            new StateCouncilSpecialAllowance(15000)
        };
        System.out.println(totalTax(incomes));
    }

    public static double totalTax(Income... incomes) {
        double total = 0;
        for (Income income: incomes) {
            total = total + income.getTax();
        }
        return total;
    }
}

class Income {
    protected double income;

    public Income(double income) {
        this.income = income;
    }

    public double getTax() {
        return income * 0.1; // 稅率10%
    }
}

class Salary extends Income {
    public Salary(double income) {
        super(income);
    }

    @Override
    public double getTax() {
        if (income <= 5000) {
            return 0;
        }
        return (income - 5000) * 0.2;
    }
}

class StateCouncilSpecialAllowance extends Income {
    public StateCouncilSpecialAllowance(double income) {
        super(income);
    }

    @Override
    public double getTax() {
        return 0;
    }
}

  • 利用多型,totalTax()方法只需要和Income打交道,它完全不需要知道SalaryStateCouncilSpecialAllowance的存在,就可以正確計算出總的稅。如果我們要新增一種稿費收入,只需要從Income派生,然後正確覆寫getTax()方法就可以。把新的型別傳入totalTax(),不需要修改任何程式碼。

抽象類

  • 由於多型的存在,每個子類都可以覆寫父類的方法
class Person {
    public void run() { … }
}

class Student extends Person {
    @Override
    public void run() { … }
}

class Teacher extends Person {
    @Override
    public void run() { … }
}

Person類派生的StudentTeacher都可以覆寫run()方法。

  • 如果一個class定義了方法,但沒有具體執行程式碼,這個方法就是抽象方法,抽象方法用abstract修飾。
  • 當我們定義了抽象類Person,以及具體的Student、Teacher子類的時候,我們可以通過抽象類Person型別去引用具體的子類的例項

後言

學到這,我回頭看去,我已經不知道我在學些什麼了,我覺得從面對物件程式設計開始,我就開始迷糊,不知道學的是什麼,只是一味的死記住,並不知道怎麼用,看著他說的一大片話只是懵懂,有時候看著看著都能發呆,導致這周也沒去學些啥,因為不知道在學些啥,我打算要換個方向去學習java了,想去看有講解的視訊去繼續學習。