Java之旅(十六)

Java 抽象类与接口差异

抽象类(Abstract Class)与接口(Interface)在Java中都是用来描述一种模板和规范的,它们在执行结构和概念上有很多相似之处,但在使用方式和特性上有明显的差异

区别与差异:

  • 抽象类和接口都可以定义常量和抽象方法。另外抽象类可以包含实例变量(成员变量),而接口不允许包含实例变量,只能定义常量。
  • 抽象类可以包含具体方法(即非抽象方法),而接口中的方法默认都是抽象方法,直到Java 8引入了默认方法(default method)和静态方法(static method),接口中才允许包含具体实现。抽象类的子类必须实现其所有的抽象方法,而接口的实现类可以实现其中的全部方法。
  • 抽象类中的方法可以有访问修饰符,如public、protected和private;接口的方法默认都是public,不允许使用private和protected修饰符。
  • 抽象类和接口都可以被继承。一个类可以实现多个接口,但只能继承一个抽象类。例如,一个类可以实现接口 A 和接口 B ,同时继承自抽象类 C 。但不能同时继承自抽象类 C 和抽象类 D 。
  • 抽象类可以有构造函数,而接口不能有构造函数。
  • 抽象类和接口都不能有实例,只能有一个实例对象被创建,它是由系统自动创建的。

如何选择使用抽象类还是接口:

  • 如果不同类之间有共同的属性和行为,可以考虑创建抽象类,在抽象类中定义共享的属性和方法,子类继承抽象类并实现特定功能;
  • 如果需要为一组对象定义一组统一的方法,但这些方法的具体实现可能在每个对象中都不同,可以考虑使用接口。

如下例子:

// 抽象类
abstract class Vehicle {
    int speed;

    void setSpeed(int speed) {
        this.speed = speed;
    }
    abstract void start();
}

class Car extends Vehicle {
    @Override
    void start() {
        System.out.println("Car started");
    }
}

// 接口
interface Flyable {
    void fly();
}

class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("Airplane is flying");
    }
}

public class ExampleMain {
    public static void main(String[] args) {
        Car car = new Car();
        car.setSpeed(60);
        car.start();

        Airplane airplane = new Airplane();
        airplane.fly();
    }
}

在这个例子中,我们可以看到:

  • Vehicle是一个抽象类,表示交通工具。它具有共性属性speed和共性方法setSpeed(),同时定义了一个抽象方法start(),表示启动。
  • Car类继承自Vehicle抽象类,实现了start()方法。
  • Flyable是一个接口,表示飞行功能。它定义了一个抽象方法fly(),表示飞行的行为。
  • Airplane类实现了Flyable接口,实现了fly()方法。

通过这个例子,可以理解如何根据不同需求选择使用抽象类或者接口。

你可能感兴趣的:(Java,java)