Java 抽象類(學習 Java 編程語言 045)

若是將一個類聲明爲 abstract,那麼這個類就是抽象類。抽象類能夠包含抽象方法、字段和具體方法。抽象類不能被實例化,但抽象類的對象變量能夠引用了一個非抽象子類的實例。java

若是自下而上在類的繼承層次結構中上移,位於上層的類更具備通用性,可能更加抽象。從某種角度看,祖先類更有通常性,人們只將它做爲派生其餘類的基類,而不是用來構造你想使用的特定的實例。例如,考慮擴展 Employee 類層次結構。員工是一我的,學生也是一我的。下面擴展咱們的類層次結構來加入類 Person 和類 Student。下圖顯示了這三個類之間的繼承關係。程序員

Person 及其子類的繼承圖

Person.javaide

public abstract class Person {
    public abstract String getDescription();

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

Employee.javathis

public class Employee extends Person {
    private double salary;
    private LocalDate hireDay;

    Employee(String name, double salary, int year, int month, int day) {
        super(name);
        this.salary = salary;
        hireDay = LocalDate.of(year, month, day);
    }
    public double getSalary() {
        return salary;
    }
    public LocalDate getHireDay() {
        return hireDay;
    }
    public String getDescription() {
        return String.format("an employee with a salary of $%.2f", salary);
    }
    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
}

Student.java3d

public class Student extends Person {
    private String major;

    public Student(String name, String major) {
        super(name);
        this.major = major;
    }

    public String getDescription() {
        return String.format("a student majoring in " + major);
    }
}

爲何要那麼麻煩提供這樣一個高層次的抽象呢?每一個人都有一些屬性,如姓名。學生與員工都有姓名屬性,所以經過引入一個公共的超類,咱們就能夠把 getName 方法放在繼承層次結構中更高的一層。code

如今,在增長一個 getDescription 方法,它能夠返回對一我的的簡短描述。例如:
an employee with a salary of $5,000.00
a student majoring in computer science
在 Employee 類和 Student 類中實現這個方法很容易。可是在 Person 類中應該提供什麼內容呢?除了姓名以外,Person 類對這我的一無所知。固然,可讓 Person.getDescription() 返回一個空字符串。不過還有一個更好地方法,就是使用 abstract 關鍵字,這樣就徹底不須要實現這個方法了。
public abstract String getDescription();orm

爲了提升程序的清晰度,包含一個或多個抽象方法的類自己必須被聲明爲抽象的。對象

public abstract class Person
{
    ...
    public abstract String getDescription();
}

除了抽象方法以外,抽象類還能夠包含字段和具體方法。例如,Person 類還保存着一我的的姓名,另外有一個返回姓名的具體方法。blog

public abstract class Person {
    public abstract String getDescription();

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

提示: 許多程序員認爲,在抽象類中不能包含具體方法。建議儘可能將通用的字段和方法(無論是不是抽象的)放在超類(無論是不是抽象類)中。繼承

抽象方法充當着佔位方法的角色,它們在子類中具體實現。

擴展抽象類能夠有兩種選擇:

  1. 在子類中保留抽象類中的部分或全部抽象方法仍未定義,這樣就必須將子類也標記爲抽象類。
  2. 定義所有的抽象方法,這樣一來,子類就不是抽象的了。

即便不含抽象方法,也能夠將類聲明爲抽象類。

抽象類不能被實例化。也就是說,若是將一個類聲明爲 abstract,就不能建立這個類的對象。

能夠定義一個抽象類的對象變量,可是這樣一個變量只能引用非抽象子類的對象。例如:
Person p = new Student("Vince Vu", "Economics"); 這裏的 p 是一個抽象類型 Person 的變量,它引用了一個非抽象子類 Student 的實例。

相關文章
相關標籤/搜索