在面向对象编程中,**抽象类(Abstract Class)**是一种不能被直接实例化,只能被其他类继承的类。它通常用来作为一组相关类的“父类模板”。
简单来说,当你遇到以下情况时,应该考虑使用抽象类:
如果你的多个子类都有一模一样的逻辑或方法,你不想在每个子类里都复制粘贴一遍,就可以把这些公共代码提取到抽象类中。
你希望所有继承它的子类,都必须实现某些特定的方法,否则编译器就报错。
如果子类之间需要共享或者操作一些共同的属性(字段/成员变量),抽象类可以很好地承载这些状态。
抽象类通常用于描述一类事物的共同本质。比如“动物”是一个抽象概念,现实中只有“狗”或“猫”,没有具体的“动物”实体,所以 Animal 应该被定义为抽象类。
假设我们在做一个游戏,里面有各种角色:
// 抽象类:游戏角色
abstract class GameCharacter {
// 1. 共享状态(成员变量)
protected String name;
protected int health;
public GameCharacter(String name, int health) {
this.name = name;
this.health = health;
}
// 2. 公共实现(具体方法):所有角色受伤逻辑都一样
public void takeDamage(int damage) {
this.health -= damage;
System.out.println(name + " 受到了 " + damage + " 点伤害,剩余血量:" + health);
}
// 3. 抽象方法(强制规范):每个角色的攻击方式必须自己实现
public abstract void attack();
}
// 子类:战士
class Warrior extends GameCharacter {
public Warrior(String name) {
super(name, 100);
}
@Override
public void attack() {
System.out.println(name + " 用剑砍了敌人一刀!");
}
}
// 子类:法师
class Mage extends GameCharacter {
public Mage(String name) {
super(name, 60);
}
@Override
public void attack() {
System.out.println(name + " 念咒语发射了火球!");
}
}
在这个例子中:
takeDamage 是所有角色共用的逻辑(放在抽象类里复用)。attack 每个角色都不同,但必须得有(用抽象方法强制子类实现)。new GameCharacter("小明", 100),因为角色必须具体是战士或法师。虽然抽象类和接口(Interface)都能定义规范,但有以下区别,决定了你该用哪个:
| 特性 | 抽象类 | 接口 |
|---|---|---|
| 关系 | 强调 “是一个” (IS-A),如狗是动物 | 强调 “能做什么” (CAN-DO),如鸟会飞 |
| 继承限制 | 大多数语言只支持单继承(一个类只能继承一个抽象类) | 支持多实现(一个类可以实现多个接口) |
| 成员变量 | 可以有普通成员变量和状态 | 一般只能有常量(或无状态) |
| 方法实现 | 可以有具体方法,也可以有抽象方法 | 现代语言(Java 8+)也支持默认方法,但主要用于扩展 |
选择建议:
当你心里出现这些念头时,就用抽象类:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。