区别
- 定义:
- 抽象类:是一种不能被实例化的类,它可以包含抽象方法(只有声明,没有实现)和具体方法(有方法体)。抽象类主要用于抽取相关类的共性,作为这些类的公共父类。
- 接口:是一种特殊的抽象类型,里面的所有方法都是抽象的(JDK 8 之前),且默认是 public 和 abstract 的,成员变量默认是 public、static 和 final 的。接口更多地是用于定义一种规范或契约。
- 继承与实现:
- 抽象类:一个类只能继承一个抽象类,这是因为 Java 单继承机制的限制。继承抽象类的子类需要实现抽象类中的抽象方法(除非子类也是抽象类)。
- 接口:一个类可以实现多个接口,通过这种方式实现多继承的效果。实现接口的类必须实现接口中定义的所有方法。
- 使用场景:
- 抽象类:当需要表达一种 “is - a” 的关系,并且相关类之间有较多的共同属性和方法时,使用抽象类。例如,所有的动物都有一些共同的属性(如名字、年龄等)和行为(如吃东西等),可以将这些共性抽取到一个抽象的
Animal
类中。
- 接口:当需要实现一种 “like - a” 的关系,或者需要为不相关的类提供通用的功能时,使用接口。比如,鸟类和飞机都可以飞行,它们之间并没有直接的继承关系,但都可以实现 “Flyable” 接口。
代码示例
抽象类示例
// 抽象类
abstract class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 抽象方法
public abstract void eat();
// 具体方法
public void sleep() {
System.out.println(name + " is sleeping.");
}
}
// 继承抽象类的子类
class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("Dog is eating bones.");
}
}
接口示例
// 接口
interface Flyable {
void fly();
}
// 实现接口的类
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("Bird is flying.");
}
}
// 另一个实现接口的类
class Airplane implements Flyable {
@Override
public void fly() {
System.out.println("Airplane is flying.");
}
}