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 中,我们可以从许多来源实现接口。