https://www.itcast.cn/mianshi/20230331/09511888655.shtml

在面向对象编程中,通常使用抽象类和接口来定义类的行为和属性。抽象类是一种具有抽象方法和非抽象方法的类,而接口是一组方法签名,没有实现。

以下是一些情况下,可能更倾向于使用抽象类而不是接口:

  1. 当需要共享代码实现时,抽象类比接口更有用。因为抽象类可以包含非抽象方法的实现,而接口只包含方法签名,不包含任何实现。如果有多个类需要共享同一套代码实现,使用抽象类可以避免代码重复。
  2. 当类之间存在共同的行为时,使用使用抽象类比使用接口更为合适。因为抽象类可以定义共同的行为,并且具有默认实现,子类只需重写其特定行为。而使用接口时,每个类都必须实现接口中定义的所有方法,无论是否需要这些方法。
  3. 当类的行为需要在未来进行扩展时,使用抽象类比使用接口更为合适。因为抽象类可以包含非抽象方法的实现,这些实现可以在子类中进行扩展。而使用接口时,每个类必须实现接口中定义的所有方法,如果需要添加新方法,则必须修改所有实现了接口的类。
  4. 当需要强制要求子类必须实现某些方法时,接口比抽象类更为合适。因为接口只包含方法签名,没有默认实现,子类必须实现接口中定义的所有方法。而抽象类可以包含非抽象方法的实现,子类可以选择不重写这些方法。

假设我们正在设计一个游戏,其中包含多种不同类型的敌人。这些敌人有共同的行为,如移动、攻击和受伤等。我们可以使用抽象类或接口来定义这些共同行为。

以下是使用抽象类定义敌人的示例代码:

public abstract class Enemy {
    private int health;
    private int speed;
    
    public Enemy(int health, int speed) {
        this.health = health;
        this.speed = speed;
    }
    
    public abstract void move();
    
    public abstract void attack();
    
    public void takeDamage(int damage) {
        health -= damage;
        if (health <= 0) {
            die();
        }
    }
    
    public void die() {
        // Default implementation for all enemies
    }
}

在上面的代码中,我们定义了一个抽象类Enemy,其中包含了敌人的一些共同属性和方法。move()和attack()方法是抽象方法,需要在具体的敌人类中实现。takeDamage()和die()方法是具有默认实现的非抽象方法,所有的敌人都可以继承这些默认实现,如果需要可以进行重写。

以下是使用接口定义敌人的示例代码: