“全栈2019”Java第五十九章:抽象类与抽象方法详解

188 阅读6分钟
原文链接: www.toutiao.com

难度

初级

学习时间

20分钟

适合人群

零基础

开发语言

Java

开发环境

  • JDK v11
  • IntelliJ IDEA v2018.3

提示

本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。

1.普通类

我们来看一个普通的继承类。

演示:

请编写一个父类,描述形状。再编写两个子类,一个描述圆形,一个描述正方形。

请观察程序有何不妥。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Circle类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Square类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

大家请看Shape类,它里面有一个绘制方法,本来它就不知道该绘制什么形状,只有子类是什么形状,他就重写draw方法来绘制什么形状。父类Shape根本不知道自己该绘制什么形状。

也就是说,父类Shape里面的draw方法根本无需实现,具体实现应该交给子类去做。我们把这种方法称为抽象方法,抽象方法是在没有实现的情况下声明的方法(没有大括号,后跟分号)

再一个,父类Shape可不可以创建对象?首先我们创建Circle对象和Square对象是因为我们知道要创建圆形和正方形,而Shape不知道要创建一个什么形状,所以说没有必要让Shape可以创建对象,也没有意义。我们把Shape这样的类称为抽象类,抽象类是一个声明为abstract的类。它可能包含也可能不包含抽象方法。抽象类无法实例化,但可以进行子类化。

2.抽象类

抽象类是一个声明为abstract的类。

声明格式:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

演示:

请编写一个抽象类。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

抽象类里面是可以拥有实例方法和类方法,现在又新增了一个抽象方法。

3.抽象方法

抽象方法是在没有实现的情况下声明的方法(没有大括号,后跟分号)。

声明格式:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

演示:

请编写一个抽象方法。

代码:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

我们可以看到抽象方法是没有具体实现的。

4.抽象类无法实例化

当声明为抽象类时,该类无法被实例化。

演示:

请编写一个抽象类,然后进行实例化,观察程序运行过程。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

结果:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

错误信息:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(9, 23) java: lab.Shape是抽象的; 无法实例化

错误原因就是抽象类无法被实例化,至于为什么?上面我们也讲过,抽象类实例化没有必要,也没有意义。

5.抽象类的子类可以实例化

虽然抽象类自身没法实例化,但是它的子类可以实例化。如果它的子类还是抽象类呢?那也是无法实例化的。

演示:

请编写一个父类,抽象的。再编写一个子类,实现其父类中抽象方法。

请实例化子类,然后观察运行结果。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Circle类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

结果:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

从运行结果来看,程序运行过程中没有发现错误。这也说明了抽象类的子类是可以被实例化的,前提是子类不是抽象类。

6.抽象类可以不包含抽象方法

当我们声明一个抽象类时,类体中可以不包含抽象方法。

演示:

请编写一个父类,为抽象类。再编写一个子类,非抽象类。

父类类体里面没有任何一个抽象方法,子类里面任意编写一个方法,然后实例化子类,调用方法。

请观察程序运行结果。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Circle类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

结果:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

从运行结果来看,程序在运行过程中没有发生任何异常。这也说明了,声明一个抽象类,类体里面可以没有一个抽象方法。

7.包含抽象方法的类一定是抽象类

当我们声明一个抽象类时,里面可以一个抽象方法都没有。但是,当我们一个类里面有一个及以上个抽象方法时,该类必须声明为抽象类。

演示:

请编写一个类,非抽象类,类体里面声明一个抽象方法。

请观察程序运行结果。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

结果:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

错误信息:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

文字版:

/Users/admin/Workspace/Java/Hello/src/lab/Shape.javaError:(6, 8) java: lab.Shape不是抽象的, 并且未覆盖lab.Shape中的抽象方法draw()

当一个类里面有抽象方法时,该类必须时抽象类。

将类声明为抽象类即可:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

8.子类未实现父类中所有抽象方法时必须也声明为抽象类

当抽象类被继承时,子类通常为其父类中的所有抽象方法提供实现。但是,如果没有,那么子类也必须声明为abstract。

演示:

请编写一个父类,为抽象类,类体有一个抽象方法。再编写一个子类,不实现其父类中抽象方法。

请观察运行结果。

代码:

Shape类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Circle类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

结果:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

错误信息:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

文字版:

/Users/admin/Workspace/Java/Hello/src/lab/Circle.java

Error:(6, 8) java: lab.Circle不是抽象的, 并且未覆盖lab.Shape中的抽象方法draw()

此时,我们可以将子类也声明为抽象类:

Circle类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

只不过就是Circle无法再实例化:

Main类:

“全栈2019”Java第五十九章:抽象类与抽象方法详解

注意

未声明为default或static的接口中的方法是隐式抽象的,因此abstract修饰符不与接口方法一起使用(可以使用,但不需要)。

接口下一章讲解。

总结

  • 抽象方法是在没有实现的情况下声明的方法(没有大括号,后跟分号)。
  • 抽象类是一个声明为abstract的类。它可能包含也可能不包含抽象方法。抽象类无法实例化,但可以进行子类化。
  • 抽象类是一个声明为abstract的类。
  • 当声明为抽象类时,该类无法被实例化。
  • 抽象类的子类(非抽象类)可以实例化。
  • 抽象类可以不包含抽象方法。
  • 包含抽象方法的类一定是抽象类。
  • 未声明为default或static的接口中的方法是隐式抽象的,因此abstract修饰符不与接口方法一起使用(可以使用,但不需要)。

至此,Java中抽象类与抽象方法相关内容讲解先告一段落,更多内容请持续关注。

答疑

如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。

上一章

“全栈2019”Java第五十八章:多态中方法返回类型是子类类型

下一章

“全栈2019”Java第六十章:如何定义接口

学习小组

加入同步学习小组,共同交流与进步。

  • 方式一:关注头条号Gorhaf,私信“Java学习小组”。
  • 方式二:关注公众号Gorhaf,回复“Java学习小组”。

全栈工程师学习计划

关注我们,加入“全栈工程师学习计划”。

“全栈2019”Java第五十九章:抽象类与抽象方法详解

版权声明

原创不易,未经允许不得转载!