Java抽象類、抽象方法詳解


1. 概述

類用於描述現實生活中一類事物。類中有屬性、方法等成員。

父類中的方法,被它的子類們重寫,子類各自的實現都不盡相同。那么父類的方法聲明和方法主體,只有聲明還有 意義,而方法主體則沒有存在的意義了。

某種情況下,父類只能知道子類應該具備一個怎樣的方法,但是不能夠明確知道如何實現該方法。只能在子類中才能確定如何去實現方法體。例如:所有幾何圖形都應該具備一個計算面積的方法。但是不同的幾何圖形計算面積的方式不同。

我們把沒有方法主體的方法稱為抽象方法。Java語法規定,包含抽象方法 的類就是抽象類

2. 抽象方法

抽象方法 : 只有方法的聲明,沒有方法體,以分號 ; 結尾,使用 abstract 關鍵字修飾

定義格式:

修飾符 abstract 返回值類型 方法名(參數列表);

代碼舉例:

public abstract void run();

抽象方法不能用private、final、static、native修飾

3. 抽象類

抽象類:包含抽象方法的類。如果一個類包含抽象方法,那么該類必須是抽象類,使用 abstract 關鍵字修飾

定義格式:

public abstract class 類名 {
    //抽象類中可以包含變量、常量,抽象方法,非抽象方法
}

代碼舉例:

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

抽象類的使用

抽象類不能實例化,不能直接創建對象。抽象類是用來被繼承的,繼承抽象類的子類必須重寫父類所有的抽象方法。否則,該子類也必須聲明為抽象類,使用 abstract 關鍵字修飾

抽象類也是類,因此原來類中可以有的成員,抽象類都可以有,那么抽象類不能直接創建對象,為什么還有構造器呢?供子類調用,子類創建對象時,需要為從父類繼承的屬性初始化。

抽象類不能使用final修飾

public class Teacher extends Person {
    public void work() {
      	System.out.println("講課"); 	 
    }
}
public class AbstractClassTest {
 	 public static void main(String[] args) {
        // 創建子類對象
        Teacher t = new Teacher(); 
       
        // 調用run方法
        t.work();
  	}
}

輸出結果:
講課

此時的方法重寫,是子類對父類抽象方法的完成實現,我們將這種方法重寫的操作,叫做實現方法

實現:去掉abstract關鍵字,加上方法體{...}

抽象類注意事項

  1. 抽象類不能創建對象,如果創建,編譯無法通過而報錯。只能創建其非抽象子類的對象。

    理解:假設創建了抽象類的對象,調用抽象的方法,而抽象方法沒有具體的方法體,沒有意義。

  2. 抽象類中,可以有構造方法,是供子類創建對象時,初始化父類成員使用的。

    理解:子類的構造方法中,有默認的super(),需要訪問父類構造方法。

  3. 抽象類中,可以有成員變量。

    理解:子類的共性的成員變量 , 可以定義在抽象父類中。

  4. 抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類。

    理解:未包含抽象方法的抽象類,聲明為抽象類目的就是不想讓使用者創建該類的對象,通常用於某些特殊的類結構設計。

  5. 抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯報錯。除非該子類也是抽象類。

    理解:假設不重寫所有抽象方法,則類中可能包含抽象方法。那么創建對象后,調用抽象的方法,沒有意義。

抽象類與普通類的區別

抽象類使用abstract修飾;普通類沒有abstract修飾

抽象類不能實例化;普通類可以實例化

抽象類可以包含抽象方法,也可以包含非抽象方法;普通類不能有抽象方法

4. abstract關鍵字

可以用來修飾的結構:類、方法,不能用來修飾變量、代碼塊、構造器

不能和 abstract 一起使用的修飾符

  • 外部類可用修飾符:abstract、final,兩種訪問修飾符:public和缺省。其中abstract和final不能一起修飾類

  • 方法可用修飾符:4種訪問修飾符,static、final、abstract、native。不能共存的:

    • private,abstract不行 因為private不能被重寫
    • static,abstract不行 因為static不能被重寫
    • final,abstract不行 因為final不能被重寫
    • native,abstract不行 因為都沒有方法體,不知道是什么情況,會有歧義

5. 抽象類簡單案例

5.1案例介紹

某IT公司有多名員工,按照員工負責的工作不同,進行了部門的划分(研發部員工、維護部員工)。研發部根據所需研發的內容不同,又分為JavaEE工程師、Android工程師;維護部根據所需維護的內容不同,又分為網絡維護工程師、硬件維護工程師。

公司的每名員工都有他們自己的員工編號、姓名,並要做它們所負責的工作。

工作內容:

  • JavaEE工程師: 員工號為xxx的 xxx員工,正在研發淘寶網站

  • Android工程師:員工號為xxx的 xxx員工,正在研發淘寶手機客戶端軟件

  • 網絡維護工程師:員工號為xxx的 xxx員工,正在檢查網絡是否暢通

  • 硬件維護工程師:員工號為xxx的 xxx員工,正在修復打印機

請根據描述,完成員工體系中所有類的定義,並指定類之間的繼承關系。進行XX工程師類的對象創建,完成工作方法的調用。

5.2 案例分析

  • 根據上述部門的描述,得出如下的員工體系圖:

  • 根據員工信息的描述,確定每個員工都有員工編號、姓名、要進行工作。則,把這些共同的屬性與功能抽取到父類中(員工類),關於工作的內容由具體的工程師來進行指定。

  • 創建JavaEE工程師對象,完成工作方法的調用

5.3 示例代碼

定義員工類(抽象類)

public abstract class Employee {
	private String id; // 員工編號
	private String name; // 員工姓名

	public String getId() {
		returnid;
	}
	publicvoid setId(String id) {
		this.id = id;
	}
	public String getName() {
		returnname;
	}
	publicvoid setName(String name) {
		this.name = name;
	}
	
	//工作方法(抽象方法)
	public abstract void work(); 
}

定義研發部員工類Developer 繼承 員工類Employee

public abstract class Developer extends Employee {
}

定義維護部員工類Maintainer 繼承 員工類Employee

public abstract class Maintainer extends Employee {
}

定義JavaEE工程師 繼承 研發部員工類,重寫工作方法

public class JavaEE extends Developer {
	@Override
	public void work() {
		System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在研發淘寶網站");
	}
}

定義Android工程師 繼承 研發部員工類,重寫工作方法

public class Android extends Developer {
	@Override
	public void work() {
		System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在研發淘寶手機客戶端軟件");
	}
}

定義Network網絡維護工程師 繼承 維護部員工類,重寫工作方法

public class Network extends Maintainer {
	@Override
	public void work() {
		System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在檢查網絡是否暢通");
	}
}

定義Hardware硬件維護工程師 繼承 維護部員工類,重寫工作方法

public class Hardware extends Maintainer {
	@Override
	public void work() {
		System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在修復打印機");
	}
}

在測試類中,創建JavaEE工程師對象,完成工作方法的調用

public class Test {
	public static void main(String[] args) {
		//創建JavaEE工程師員工對象
		JavaEE ee = new JavaEE();
		//設置該員工的編號
		ee.setId("111111");
		//設置該員工的姓名
		ee.setName("張偉");
		//調用該員工的工作方法
		ee.work();
	}
}


免責聲明!

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



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