【JAVA】基础知识“抽象类”详解,从入门到理解~
目录
1. 抽象类
1.1 什么是抽象类❓
1.2 为什么需要抽象类❓
1.3 抽象类语法
1.4 抽象类特征
① 抽象类是被abstract修饰的
② 被abstract修饰的方法称为抽象方法,这个方法可以没有具体的实现
③ 当一个类中含有抽象方法的时候,该类必须使用abstract修饰
④抽象类当中可以和普通类一样有成员变量,成员方法,也可以有构造方法
⑤ 抽象类不可以被实例化
⑥ 当一个普通类去继承我们的抽象类时,这个普通类一定要去重写我们这个抽象类里面所有的抽象方法。
⑦ final 和abstract 是不能同时存在的
⑧ 当一个抽象类A不想被一个普通类B继承时,可以把这个B类变成抽象类,那么再当一个普通类C继承这个类之后,C类要重写B和A里面所有的抽象方法。
1.5 抽象类的作用
对比表格(抽象类 vs 普通类)
1. 抽象类
1.1 什么是抽象类❓
我们知道,在面向对象的概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描绘对象的。
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类好比建筑设计图纸,它定义了房屋的基本结构(框架方法),但是暂时不会实现具体的细节(比如墙面涂料的颜色等等)。在java中,抽象类使用abstract关键字声名,可以包含普通方法和抽象方法。
1.2 为什么需要抽象类❓
想象一下我们要设计一个"图形绘画系统",系统中需要我们绘画出矩形、圆形等图形。这时可以创建一个Shape
类作为父类,Rect(矩形),Cycle(圆形)这两个作为子类,但draw()
方法在不同图形中的实现各不相同。
我们先看一个未使用抽象类的反例:off the hook
//定义了一个父类Shape
class Shape {public void draw() {// 这里应该怎么写?}
}
这时候就有问题了,我们的矩形和圆形图形都需要绘制,但是父类Shape根本不知道具体怎么绘制,里面没有足够的信息去描绘具体的矩形和圆形。而且如果子类忘记重写draw()方法,程序也不会报错,这也会导致安全隐患。这个时候就需要抽象类啦~
1.3 抽象类语法
java中一个类如果被 abstract 修饰称为抽象类。
抽象类中被 abstract 修饰的方法称为抽象方法,
// 抽象类声明
abstract class Shape {// 抽象方法声明(没有方法体)public abstract void draw();
}
1.4 抽象类特征
下面我们具体讲解抽象类特征的一些详细知识点:
① 抽象类是被abstract修饰的
② 被abstract修饰的方法称为抽象方法,这个方法可以没有具体的实现
③ 当一个类中含有抽象方法的时候,该类必须使用abstract修饰
可以看到方法被abstract修饰时,若是该类没有被abstract修饰,会产生错误。则一个类里面如果有抽象方法,这个类一定要用abstract修饰,变为抽象类。
④抽象类当中可以和普通类一样有成员变量,成员方法,也可以有构造方法
⑤ 抽象类不可以被实例化
这时候我们如果实例化Shape,会报错,会显示:
我们看到现在,发现抽象类不能被实例化,抽象类的作用就是为了被继承~
那么我们定义一个Rect类去继承Shape类时,会发现也出现了错误:
这就是下一个注意事项:
⑥ 当一个普通类去继承我们的抽象类时,这个普通类一定要去重写我们这个抽象类里面所有的抽象方法。
这个时候重写父类的方法后,就不会报错啦~
⑦ final 和abstract 是不能同时存在的
可以看到添加 final 后报错了 这是因为:
abstract
(抽象方法):
抽象方法没有方法体,必须在子类中被重写。
final
(不可变/不可继承):
final
修饰的方法不能被子类重写。
final
修饰的类不能被继承。
abstract
要求子类必须重写该方法。而final
却禁止子类重写该方法。👉 final abstract
组合会导致逻辑冲突啦~
抽象类中也可以发生向上转型,实现多态,下面是一段完整的代码:
// 定义一个抽象类 Shape,表示"形状"的基类
// 抽象类不能被实例化,主要用于被子类继承
abstract class Shape {// 定义抽象方法 draw()public abstract void draw();
}
// Rect 类继承自 Shape,表示"矩形"
class Rect extends Shape {@Override//重写父类的方法public void draw() {System.out.println("矩形");}
}
// Cycle 类继承自 Shape,表示"圆形"
class Cycle extends Shape {@Overridepublic void draw() {System.out.println("圆");}
}
public class Test {// 定义一个静态方法 drawMethod,参数类型是 Shape(多态的体现)// 可以接收任何 Shape 的子类对象(如 Rect、Cycle)public static void drawMethod(Shape shape) {shape.draw();// 调用传入对象的 draw() 方法}public static void main(String[] args) {//Shape shape = new Shape();抽象类不能直接实例化Shape shape = new Rect();//向上转型:父类引用指向子类对象// 调用 drawMethod,传入匿名 Rect 对象drawMethod(new Rect());//new Rect()是匿名对象,没有名字的对象// 调用 drawMethod,传入匿名 Cycle 对象drawMethod(new Cycle());}}
⑧ 当一个抽象类A不想被一个普通类B继承时,可以把这个B类变成抽象类,那么再当一个普通类C继承这个类之后,C类要重写B和A里面所有的抽象方法。
我们可以看到抽象类Shape不想被普通类A继承,所以讲A类变成了抽象类,加上了abstract,当我们一个普通类C去继承这个A类后,C类里面要重写Shape的抽象方法,也要重写A里面的抽象方法。
1.5 抽象类的作用
🌟 博主是这么理解的:普通类是完整的"成品",抽象类是"半成品模板"~
-
普通类可以直接用(能
new
创建对象) -
抽象类不能直接用(必须让子类继承完善后才能用)
🍎 我们拿生活例子来比喻一下,比如说我们想象做月饼:
-
普通类 = 现成的月饼(直接能吃)
-
抽象类 = 月饼模具(规定了形状,但需要你填入馅料才能用)
对比表格(抽象类 vs 普通类)
特性 | 抽象类 | 普通类 |
---|---|---|
能否直接创建对象 | ❌ 不能 (new 会报错) | ✅ 能 |
包含抽象方法 | ✅ 可以有不实现的方法 | ❌ 不能有 |
主要用途 | 当父类定义规范 | 直接使用 |
代码复用 | ✅ 可以放公共代码 | ✅ 也可以 |
继承时的要求 | 子类必须实现所有抽象方法 | 子类可自由选择重写方法 |
制作不易,更多内容加载中~感谢友友们的点赞收藏关注~~
如有问题欢迎批评指正,祝友友们生活愉快,学习工作顺顺利利!