接口与抽象类
目录
- 一、抽象类
- 二、接口
- 三、使用场景
- 四、示例代码
抽象类(Abstract Class)和接口(Interface)在 Java 中都是用来实现代码的抽象化和封装,但它们之间有一些关键的区别和用途。
一、抽象类
- 定义:抽象类是使用
abstract
关键字定义的类,它可以包含抽象方法和具体方法。 - 构造方法:抽象类不能被实例化,但可以有构造方法,这些构造方法只能在子类中被调用。
- 成员变量:可以有实例变量和类变量,并且可以给实例变量赋初始值。
- 方法实现:可以包含已经实现的方法和没有实现的抽象方法。
- 继承:一个类只能继承一个抽象类。
- 访问修饰符:抽象方法必须被声明为
public
或protected
(默认),不能是private
。 - 多态:抽象类可以实现多态,但需要通过子类来实现。
二、接口
- 定义:接口是使用
interface
关键字定义的,完全抽象的类型。 - 构造方法:接口不能有构造方法。
- 成员变量:接口中的所有变量默认都是
public static final
的,即常量。 - 方法实现:在 Java 8 之前,接口中的方法默认是抽象的,不能有实现。从 Java 8 开始,接口可以包含默认方法和静态方法。
- 继承:一个类可以实现多个接口。
- 访问修饰符:接口中的方法默认是
public
的,并且不能有private
方法。 - 多态:接口天生就是为了实现多态。
三、使用场景
- 抽象类:
- 当你有一个共同的基类,它包含一些公共的属性和方法,但同时也有一些需要子类去实现的抽象方法时,使用抽象类是合适的。
- 当类层次结构中的一些类共享相同的属性和方法,并且这些方法有共同的实现时,抽象类可以提供这些共同的实现。
- 当你需要提供某些默认行为时,抽象类可以提供默认方法的实现。
- 接口:
- 当你想要为多个类提供多态行为时,接口是理想的选择。它们允许不同的类以统一的方式被处理。
- 当你想要强制类实现某些方法时,接口可以定义这些方法,确保所有实现该接口的类都遵循相同的契约。
- 当你想要实现回调机制时,例如事件监听器模式,接口可以用来定义回调方法
四、示例代码
// 抽象类示例
abstract class Animal {
abstract void makeSound();
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("Woof woof!");
}
}
// 接口示例
interface Movable {
void move();
}
interface Flyable {
void fly();
}
class Bird implements Movable, Flyable {
public void move() {
System.out.println("The bird is running.");
}
public void fly() {
System.out.println("The bird is flying.");
}
}
在这个例子中,Animal 是一个抽象类,它定义了所有动物共有的行为 eat,并且有一个抽象方法 makeSound 需要子类 Dog 去实现。而 Movable 和 Flyable 是接口,它们定义了 Bird 类必须实现的行为。