Java中的抽像類和抽象方法是什麼? 我應該什麼時候使用它? 附教程
已發表: 2019-09-12
幾天前,我寫了一篇關於 Java 基礎知識的文章,關於什麼是 Java 中的接口以及如何使用它? 本教程還涉及基本的 Java 基礎“ Abstract Class and Abstract Method
”。
什麼是抽像類?
讓我們先了解 Abstract 類,然後再看 Example。
- 抽像類是聲明為
abstract
的類 - 抽像類不能被實例化
- 抽像類可以被子類化
- 它可能包含也可能不包含抽象方法
- 當抽像類
subclassed
化時,子類通常為其父類中的所有抽象方法提供實現。 - 如果子類不提供實現,那麼子類也必須聲明為
abstract
。
這是一個非常basic Java Interview Question
。 可能是您在面試中遇到的1 st Java Interview Question
。
我可以在不添加抽象方法的情況下定義抽像類嗎?
當然是的。 聲明類抽象僅意味著您不允許它自己實例化。 非抽像類中不能有抽象方法。
什麼是抽象方法?
-
abstract method
是在沒有實現的情況下聲明的方法。 - 它只有一個方法簽名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package crunchify . com . tutorial ; /** * @author Crunchify.com * Simple Abstract Class and Method Example with live result * */ public abstract class CrunchifyExam { public enum ExamStatus { PASSED , FAILED } private String examTime ; private ExamStatus status ; public CrunchifyExam ( String examTime , ExamStatus status ) { this . examTime = examTime ; this . status = status ; } public String getExamTime ( ) { return examTime ; } public void setExamTime ( String examTime ) { this . examTime = examTime ; } public void setExamStatus ( ExamStatus status ) { this . status = status ; } public ExamStatus getExamStatus ( ) { return status ; } abstract public void checkResult ( ) ; } |
讓我們從一個例子開始。 問題描述:
- 創建
CrunchifyExam.java
類,它有一個名為checkResult()
的抽象方法 - 創建類
Crunchify1stSchoolExamResult.java
,它擴展抽像類CrunchifyExam.java
- 創建類
Crunchify2ndSchoolExamResult.java
,它擴展抽像類CrunchifyExam.java
- 現在以上兩個類都必須提供 checkResult() 方法的實現
- 兩所學校可能有自己不同的
procedure
或number of checks
來確定用戶是PASSED or FAILED
,他們可以自由地擁有自己的checkResult()
實現
在Crunchify1stSchoolExamResult.java
中擴展CrunchifyExam
類後,Eclipse 將提示您實現CrunchifyExam.java
中提到的抽象方法

Crunchify1 st SchoolExamResult.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package crunchify . com . tutorial ; /** * @author Crunchify.com */ public class Crunchify1stSchoolExamResult extends CrunchifyExam { public Crunchify1stSchoolExamResult ( String examTime , ExamStatus status ) { super ( examTime , status ) ; // TODO Auto-generated constructor stub } @Override public void checkResult ( ) { String studentName = "Crunchify1" ; String studentResult = "85%" ; // School NO-1 will provide all their formula to find if user is passed or failed. // After detailed calculation let's say student's grade is "PASSED". System . out . println ( "Hey.. this is user " + studentName + " with grade " + studentResult + " - " + getExamStatus ( ) + ", ExamTime: " + getExamTime ( ) ) ; } } |
Crunchify2 nd SchoolExamResult.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
package crunchify . com . tutorial ; import java . text . DateFormat ; import java . text . SimpleDateFormat ; import java . util . Date ; /** * @author Crunchify.com */ public class Crunchify2ndSchoolExamResult extends CrunchifyExam { public Crunchify2ndSchoolExamResult ( String examTime , ExamStatus status ) { super ( examTime , status ) ; } @Override public void checkResult ( ) { String studentName = "Crunchify2" ; String studentResult = "45%" ; // School NO-2 will provide all their formula to find if user is passed or failed. // After detailed calculation let's say student's grade is "FAILED". log ( "Hey.. this is user " + studentName + " with grade " + studentResult + " - " + getExamStatus ( ) + ", ExamTime: " + getExamTime ( ) ) ; } public static void main ( String args [ ] ) { DateFormat dateFormat = new SimpleDateFormat ( "yyyy/MM/dd HH:mm:ss" ) ; // 1st School's checkResult() Date date = new Date ( ) ; String examTime = dateFormat . format ( date ) ; log ( "Initializing 1st School object at time " + examTime ) ; // We are setting up time and Result for 1st School Crunchify1stSchoolExamResult object = new Crunchify1stSchoolExamResult ( examTime , ExamStatus . PASSED ) ; object . checkResult ( ) ; // Let's wait 5 seconds wait to see time difference in console log try { Thread . sleep ( 5000 ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } // 2nd School's checkResult() date = new Date ( ) ; examTime = dateFormat . format ( date ) ; log ( "\nInitializing 2nd School object at time " + examTime ) ; // We are setting up time and Result for 2nd School Crunchify2ndSchoolExamResult object2 = new Crunchify2ndSchoolExamResult ( examTime , ExamStatus . FAILED ) ; object2 . checkResult ( ) ; } // Simple log method private static void log ( String value ) { System . out . println ( value ) ; } } |
Eclipse 控制台結果:
只需右鍵單擊Crunchify2ndSchoolExamResult.java
並作為Java Application
運行以查看以下結果。

1 2 3 4 5 |
Initializing 1st School object at time 2016 / 11 / 30 14 : 24 : 37 Hey . . this is user Crunchify1 with grade 85 % - PASSED ExamTime : 2016 / 11 / 30 14 : 24 : 37 Initializing 2nd School object at time 2016 / 11 / 30 14 : 24 : 42 Hey . . this is user Crunchify2 with grade 45 % - FAILED ExamTime : 2016 / 11 / 30 14 : 24 : 42 |
現在你可能有一個問題
為什麼我不能在這裡使用接口而不是使用Abstract Method
和Class
並將 CrunchifyExam 作為接口?
好吧—— Sure you could
——但你還需要實現getExamTime
()、 setExamTime
()、 getExamTime
()、 setExamTime
() 方法。
通過使用抽像類,您可以繼承其他(非抽象)方法的實現。 你不能用接口做到這一點——接口cannot provide
任何方法實現。
是否可以在 Java 中創建抽像類和最終類?
- 抽象和最終是相互排斥的概念。
- 所以答案是否定的,我們不能在 Java 中使抽像類或方法成為最終的。
- final 類是完整的類,不能進一步擴展。
- 抽像類稱為不完整類,只能由其他具體類擴展,必須實現所有抽象方法。
- 此外,沒有辦法,也不可能在最終類中有抽象方法。
是否可以從 Java 中的多個抽像類繼承?
- Java 不支持多重繼承。
- 在java中我們只能擴展一個類。
- 在 Java 中,我們可以從許多來源實現接口。