抽象類的引出與深入理解
目錄:
- 抽象類的引出與深入理解
- 1. 引出抽象類:
- 2. 抽象類細節:
- 2.1 抽象類的介紹:
- 2.2 抽象類注意事項和細節討論:
- 3. 實作一個抽象類:
- 4. 抽象類作用:
1. 引出抽象類:
我們首先來看這樣一段代碼:Animal是父類,我們需要一些子類來繼承父類

package com.haut.iot.assassin;
public class Animal {
private String name; //名字
private int age; //年齡
public Animal(String name, int age) {//構造方法
this.name = name;
this.age = age;
}
//動物都有的eat行為
//思考:這里eat是實作了,其實并沒有什么意義
//即:父類方法不確定性的問題
//====> 考慮將該方法設計為抽象方法(abstract)
//====> 所謂抽象方法就是沒有實作的方法,所謂沒有實作就是沒有方法體,只有宣告
//====> 當一個類中存在抽象方法時,需要將該類宣告成為抽象類
public void eat() {
System.out.println("這是一個動物,但是目前來說不知道吃什么~");
}
}
通過上述代碼我們可以發現,父類方法存在不確定性
小結:當父類的某些方法需要宣告,但是又不確定如何實作時,可以將其宣告為抽象方法,那么這個類就是抽象類
like this:

package com.haut.iot.assassin;
public abstract class Animal { //抽象類
private String name; //名字
private int age; //年齡
public Animal(String name, int age) {//構造方法
this.name = name;
this.age = age;
}
//動物都有的eat行為
// public void eat() {
// System.out.println("這是一個動物,但是目前來說不知道吃什么~");
// }
public abstract void eat(); //抽象方法
}
一般來說,抽象類會被繼承,由其子類來實作抽象方法
2. 抽象類細節:
2.1 抽象類的介紹:
- 用
abstract關鍵字來修飾一個類時,這個類就叫做抽象類,具體語法是:訪問修飾符abstract類名 {} - 用
abstract關鍵字來修飾一個方法時,這個方法就是抽象方法,具體語法是:訪問修飾符abstract回傳型別 方法名(引數串列); //沒有方法體 - 抽象類的價值更多是體現在于設計,是設計者設計好后,讓子類繼承并實作抽象類
- 這里插一句,抽象類是面試時經常被問到的知識點,在框架和設計模式中使用較多
2.2 抽象類注意事項和細節討論:
8個細節如下:
- 抽象類不能被實體化,這里待會兒會舉例說明
- 抽象類不一定要包含
abstract方法,也就是說,抽象類可以沒有abstract方法,下面也會舉例說明 - 一旦類包含了
abstract方法,則這個類必須宣告為abstract abstract只能修飾類和方法,不能修飾屬性和其他的,這里也會舉例說明- 抽象類可以擁有任意成員(抽象類的本質還是一個類),比如:非抽象方法,構造方法,靜態屬性等
- 抽象方法不能擁有方法體,即不能實作
- 如果一個類繼承了抽象類,則它必須實作抽象類的所有抽象方法,除非它自己也宣告為
abstract類,下面會進行舉例~ - 抽象方法不能用
private,final以及static來修飾,因為這些關鍵字和重寫是相違背的,這個很重要,下面會舉例說明
抽象類不能被實體化:

抽象類可以沒有abstract方法:
可以看到 IDEA 并沒有報錯~

abstract只能修飾類和方法,不能修飾屬性和其他的:

如果一個類繼承了抽象類,則它必須實作抽象類的所有抽象方法,除非它自己也宣告為abstract類:
當子類不實作父類的抽象方法時,會報錯~,如下圖所示:

當子類也宣告為abstract類時,可以不實作父類的abstract方法:

這里再深入探討一哈,當再有一個C類繼承了B類時,A類中的抽象方法還是需要被實作,出來混總是要還的[doge]~

抽象方法不能用private,final以及static來修飾:
我們反推一哈:如果private修飾abstract語法上通過了,那子類也沒有機會去重寫或者實作此抽象方法,所以private不能修飾抽象方法

final的本意就是最終的,不想改變的意思,也就是說不希望子類來重寫此方法,所以final也不能修飾抽象方法

static可以通過類名來呼叫,所以是需要有方法體的,而抽象方法沒有方法體,自然也就不能使用static修飾抽象方法

3. 實作一個抽象類:
題面如下:
撰寫一個Employee類,宣告為抽象類,包含如下三個屬性:name,id,salary,提供必要的構造方法和抽象方法:work(),對于Manager類來說,它既是員工,還具有獎金(bonus)屬性,請使用繼承的思想,設計CommonEmployee類和Manager類,要求類中提供必要的方法進行屬性訪問,實作work(),提示“經理/普通員工 名字 作業中…”
實作代碼:
父類Employee類:
//父類Employee類
package com.haut.iot.assassin;
public abstract class Employee {
private String name; //姓名
private int id; //編號
private double salary; //薪水
public Employee(String name, int id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public abstract void work();//抽象方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
子類Manager類:
//子類Manager類
package com.haut.iot.assassin;
public class Manager extends Employee {
private double bonus; //獎金
public Manager(String name, int id, double salary) {
super(name, id, salary);
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("經理 " + getName() + " 作業中...");
}
}
子類CommonEmployee類:
//子類CommonEmployee類
package com.haut.iot.assassin;
public class CommonEmployee extends Employee{
public CommonEmployee(String name, int id, double salary) {
super(name, id, salary);
}
@Override
public void work() {
System.out.println("普通員工 " + getName() + " 作業中...");
}
}
測驗類AbstractExercise類:
//測驗類AbstractExercise類
package com.haut.iot.assassin;
public class AbstractExercise {
public static void main(String[] args) {
//測驗
Manager assassin = new Manager("assassin", 1000, 20000);
assassin.setBonus(8000);
assassin.work();
CommonEmployee ninghai = new CommonEmployee("ninghai", 999, 5000);
ninghai.work();
}
}
運行結果:

4. 抽象類作用:
抽象類存在的最大意義就是為了被繼承, 抽象類本身不能被實體化, 要想使用,只能創建該抽象類的子類,然后讓子類重寫抽象類中的抽象方法,
有些小伙伴可能會說了, 普通的類也可以被繼承呀, 普通的方法也可以被重寫呀, 為啥非得用抽象類和抽象方法呢?
確實如此,但是使用抽象類相當于多了一重編譯器的校驗,
使用抽象類的場景就如上面的代碼,實際作業不應該由父類完成,而應由子類完成,那么此時如果不小心誤用成父類了,使用普通類的話編譯器是不會報錯的, 但是父類是抽象類就會在實體化的時候提示錯誤,讓我們盡早發現問題,
很多語法存在的意義都是為了 " 預防出錯 " , 例如 final 也是類似的作用,創建的變數用戶不去修改,不就相當于常量嘛? 但是加上 final 能夠在不小心誤修改的時候, 讓編譯器及時提醒我們,充分利用編譯器的校驗,在實際開發中是非常有意義的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/337683.html
標籤:java
