Java 抽象類 抽象方法 使用說明


知識點

  • 什么是抽象類
    抽象類與普通類主要兩點不同:
    1、在類的修飾符后面多了一個abstract關鍵字
    2、抽象類是不允許通過new來實例化的
    由於抽象類不能通過new來實例化,所以基本上是在繼承中當做父類使用。

  • 什么是抽象方法
    抽象方法的定義需要加上abstract關鍵字,不能有方法體,以封號結尾,比如:
    public abstract void getOtherSalary();
    抽象方法的具體實現,需要在子類中實現。注意:static、final的方法,不能被申明為抽象方法。

  • 抽象類與抽象方法
    抽象類不一定包含抽象方法,但如果一個類包含了抽象方法,那這個類一定是抽象類,否則編譯不通過。

  • 什么時候用抽象方法
    抽象方法通常用於父類中。父類通常都是用於定義一些公共方法、公共屬性等,但是實際項目可能會出現某些方法定義在父類中,父類卻無法給出具體的實現,此時就是抽象方法出場的時候了。比如下文實例中,職員在公司中的收入都包含基本工資以及績效獎金,基本工資大家都一樣,但是績效獎金就因崗位而異了,所以績效獎金在職員類中只是個方法體,沒有具體實現。

  • 抽象方法與設計模式
    抽象方法在設計模式中有比較多的體現,特別是用於 模板方法設計模式,詳見下文實例

實例

1.抽象方法的使用

需求描述:公司里的職員分為普通程序員和技術總監,所有職員的基本薪水都是10000元每個月,程序員的績效獎金每個月3000元,技術總監的績效獎金每個月20000元。

了解了需求后,我們先定義一個職員類Employee,如下:

/**
 * 定義職工類,每個職工的薪水都由基本薪資跟績效獎金組成
 */
public abstract class Employee {

    /**
     * 崗位名稱
     */
    private String jobName;

    /**
     * 所有職工的每月基本薪資都一樣
     * @return
     */
    public int getBaseSalary(){
        return 10000;
    }

    /**
     * 所有職工都有績效獎金,但是普通程序員跟技術總監的不一樣,
     * 所以這里無法給出具體實現,需要在子類中實現
     * @return
     */
    public abstract int getOtherSalary();

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
}

定義程序員類Coder,繼承職員類,實現getOtherSalary() 方法,如下:

/**
 * 程序員類,繼承Employee類
 */
public class Coder extends Employee{

    /**
     * 由於繼承了Employee類,所以必須實現Employee類中的抽象方法getOtherSalary()
     * @return
     */
    @Override
    public int getOtherSalary() {
        return 3000;
    }
}

定義技術總監類Cto,繼承職員類,實現getOtherSalary() 方法,如下:

/**
 * 技術總監類,繼承Employee類
 */
public class Cto extends Employee{

    /**
     * 由於繼承了Employee類,所以必須實現Employee類中的抽象方法getOtherSalary()
     * @return
     */
    @Override
    public int getOtherSalary() {
        return 20000;
    }
}

最后打印程序員與技術總監每個月的薪水:

public class AbstractMain {

    public static void main(String[] args){
        Coder coder = new Coder();
        coder.setJobName("程序員");
        System.out.println(coder.getJobName() + "每個月薪資為:");
        System.out.println("基本薪資:" + coder.getBaseSalary() + "元");
        System.out.println("績效獎金:" + coder.getOtherSalary() + "元");

        Cto cto = new Cto();
        cto.setJobName("技術總監");
        System.out.println(cto.getJobName() + "每個月薪資為:");
        System.out.println("基本薪資:" + cto.getBaseSalary() + "元");
        System.out.println("績效獎金:" + cto.getOtherSalary() + "元");
    }
}

執行以上程序后,輸出:

程序員每個月薪資為:
基本薪資:10000元
績效獎金:3000元

技術總監每個月薪資為:
基本薪資:10000元
績效獎金:20000元

2.抽象方法與模板方法設計模式

在完成了以上需求后,此時又提出新需求,按照以下格式打印每個月的工資條,並且打印的順序必須按以下格式打印出來:

XXX每個月薪資為:
基本薪資:XXX元
績效獎金:XXX元
該月總工資為:XXX元

按照第一個例子的實現方式無法滿足這個需求,第一個例子的打印順序是由調用者決定的,無法統一控制。此時就是模板方法設計模式登場的時候了。基於第一個例子,改造一下職員類Employee,增加打印工資條的方法public final void printSalary()如下:

/**
 * 定義職工類,每個職工的薪水都由基本薪資跟績效獎金組成
 */
public abstract class Employee {

    /**
     * 崗位名稱
     */
    private String jobName;

    /**
     * 所有職工的每月基本薪資都一樣
     * @return
     */
    public int getBaseSalary(){
        return 10000;
    }

    /**
     * 所有職工都有績效獎金,但是普通程序員跟技術總監的不一樣,
     * 所以這里無法給出具體實現,需要在子類中實現
     * @return
     */
    public abstract int getOtherSalary();

    /**
     * 獲取每個月工資總額
     * @return
     */
    public int getTotalSalary(){

        return this.getBaseSalary() + this.getOtherSalary();
    }

    /**
     * 定義執行順序模板,模板中有些方法(抽象方法)是要在子類中實現
     * 打印工資條,定義為final類,禁止被子類重寫
     */
    public final void printSalary(){

        System.out.println(this.jobName + "每個月薪資為:");
        System.out.println("基本薪資:" + this.getBaseSalary() + "元");
        System.out.println("績效獎金:" + this.getOtherSalary() + "元");
        System.out.println("該月總工資為:" + getTotalSalary() + "元");
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
}

打印每個月工資條:

public class AbstractMain {

    public static void main(String[] args){
        Coder coder = new Coder();
        coder.setJobName("程序員");
        coder.printSalary();

        Cto cto = new Cto();
        cto.setJobName("技術總監");
        cto.printSalary();
    }
}

以上執行結果為:

程序員每個月薪資為:
基本薪資:10000元
績效獎金:3000元
該月總工資為:13000元

技術總監每個月薪資為:
基本薪資:10000元
績效獎金:20000元
該月總工資為:30000元

源碼獲取

以上示例都可以通過我的GitHub獲取完整的代碼,點擊獲取


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM