先导:
为了更好的让大家了解多态的思想,有些知识是必须要补充的,其中,抽象类和接口是非常重要的。
本篇文章我们旨在解决如下问题。
1. 什么是抽象类?
2. 抽象类如何使用?
那么本文现在正式开始。
1. 抽象类
1.1 为什么会有抽象类?
在介绍抽象类之前,我们需要先看一段代码。
class Shape {
public void draw() {
System.out.println("画图形!");
}
}
class Rect extends Shape{
@Override
public void draw() {
System.out.println("♦");
}
}
class Cycle extends Shape{
@Override
public void draw() {
System.out.println("●");
}
}
class Flower extends Shape{
@Override
public void draw() {
System.out.println("❀");
}
}
class test{
public static void drawShapes() {
// 我们创建了一个 Shape 对象的数组.
Shape[] shapes = {new Cycle(), new Rect(), new Cycle(),
new Rect(), new Flower()};
for (Shape shape : shapes) {
shape.draw();
}
}
public static void main(String[] args) {
drawShapes();
}
}
我们看了这一段代码,其实这一段代码让我们简单的接触到了多态,同时简单的理解了一下多态。但是我们再细看这一段代码,会发现有些地方貌似“不对劲”。
我们在来看父类-Shape类,你会发现这个类当中的draw方法由于被每一个子类都重写了,也就是说,这个draw方法貌似实不实现都无所谓,因为根本不会被调用。
那么如果我们不对这个方法进行任何的描写,直接打一个分号,IDEA会报错(因为Java太安全了)。
随着我们代码越来越复杂,如果一个父类当中有很多方法,但是这些方法都被子类重写了,那么如果要挨个填充无意义的代码既费时又费力,那么有没有一种类,可以在继承的时候不需要填充父类的方法呢?
这就是抽象类!!!
我们来看看抽象类的概念。
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类就是拿来被继承的!!!!!!!
1.2 抽象类的语法
抽象抽象,抽象的英文是abstract,那么在Java中,只要我们在类名之前加上一个abstract来修饰,那么这个类就是抽象类。
我们还是以Shape类来举例。
但是这个抽象类当中的draw方法如果我们去掉花括号中的内容,IDEA依然会报错,那么如果我们将抽象类中的方法也加上一个abstract修饰符,那么这个方法就变成了抽象方法,也不需要对方法进行实现。
具体就像这样。
但是,抽象类也有很多的限制!!!
1.3 抽象类的使用须知
这里面的我们一点点讲。
第一二点我们不解释了。但是我们要补充一点,通过前面的实践,抽象类当中也可以包含普通的方法。
第三点,这个很重要,因为普通类的每一个方法都有具体的实现,根本不可能包含抽象方法,如果有,那只可能是抽象方法。
第四点,因为抽象类就是拿来被继承的,所以有些成员变量和有实现的方法都是可以的。
第五点,这个很重要。因为抽象类肯定含有抽象方法,如果能够实例化,那么这个方法肯定要被调用,结果调用了发现函数没有实现,IDEA就会报错,从逻辑上来说肯定是自相矛盾的。而且如果你真的填充了抽象类里面的所有方法,那你把他设置为抽象类干什么???
第六点不说了。
第七点,这个非常重要!因为抽象类被发明就是要被继承的。所以,在设计之初,抽象类里面含有的抽象方法就是被精简过(这里我要说明一下,在正经的业务需求里,项目设计之初就要严格讨论是否需要实现抽象类,为了教学知识所以我们才句一些特殊的例子,不然正常人谁这么写代码啊),只留下需要实现的部分,那么所有的子类肯定要全部重写这些方法!!!如果不重写,那你设计抽象类干嘛!!!!!!!!!!!!!!
第八点,这个可以说明,final表示当前类、变量、方法不能被继承,但是抽象类一定要被继承,否则失去意义,所以他们两个可以视作世仇。而private修饰的方法不能跨类使用,那么连最起码的继承环境都不能满足,何谈抽象?static同理。
第九点参照第七点的讲解即可。