Java 接口与抽象类
接口和抽象类是 Java 实现多态和代码抽象的重要机制。
抽象类(Abstract Class)
什么是抽象类
抽象类是不能被实例化的类,用于定义子类必须实现的抽象方法。
// 抽象类:使用 abstract 关键字
public abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
// 抽象方法:只有声明,没有实现
// 子类必须实现抽象方法
public abstract void makeSound();
// 普通方法:可以有实现
public void eat() {
System.out.println(name + " 正在吃东西");
}
// 抽象类可以有构造方法
// 抽象类可以有成员变量
// 抽象类可以有普通方法
}
// 子类必须实现抽象方法
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " 汪汪叫");
}
}
// 如果子类不实现所有抽象方法,子类也必须是抽象的
public abstract class Mammal extends Animal {
public Mammal(String name) {
super(name);
}
// 没有实现 makeSound(),所以 Mammal 也是抽象类
}抽象类的特点
public abstract class AbstractExample {
// 1. 可以包含抽象方法
public abstract void abstractMethod();
// 2. 可以包含普通方法
public void normalMethod() {
System.out.println("普通方法");
}
// 3. 可以包含成员变量
protected int value = 10;
// 4. 可以包含构造方法
public AbstractExample() {
System.out.println("抽象类构造方法");
}
// 5. 不能实例化
// AbstractExample obj = new AbstractExample(); // 错误
// 6. 可以有静态方法
public static void staticMethod() {
System.out.println("静态方法");
}
}接口(Interface)
什么是接口
接口是一组抽象方法的集合,定义了一个类应该实现的方法。
// 接口定义:使用 interface 关键字
public interface Flyable {
// 接口中的方法默认是 public abstract
void fly(); // 等价于 public abstract void fly();
// Java 8+ 可以在接口中定义默认方法
default void land() {
System.out.println("着陆");
}
// Java 8+ 可以在接口中定义静态方法
static void showInfo() {
System.out.println("这是一个可飞行的接口");
}
}
// 类实现接口:使用 implements 关键字
public class Bird implements Flyable {
@Override
public void fly() {
System.out.println("鸟在飞");
}
}
// 一个类可以实现多个接口
public interface Swimmable {
void swim();
}
public class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子飞");
}
@Override
public void swim() {
System.out.println("鸭子游");
}
}接口的特点
public interface InterfaceExample {
// 1. 接口中的方法默认是 public abstract
void method1();
// 2. 接口中的变量默认是 public static final(常量)
int MAX_SIZE = 100; // 等价于 public static final int MAX_SIZE = 100;
// 3. Java 8+ 支持默认方法
default void defaultMethod() {
System.out.println("默认方法");
}
// 4. Java 8+ 支持静态方法
static void staticMethod() {
System.out.println("静态方法");
}
// 5. Java 9+ 支持私有方法
private void privateMethod() {
System.out.println("私有方法");
}
}接口的继承
// 接口可以继承其他接口
public interface Animal {
void eat();
}
public interface Flyable {
void fly();
}
// 接口可以多继承
public interface Bird extends Animal, Flyable {
void sing();
}
// 实现接口的类必须实现所有方法
public class Sparrow implements Bird {
@Override
public void eat() {
System.out.println("麻雀吃");
}
@Override
public void fly() {
System.out.println("麻雀飞");
}
@Override
public void sing() {
System.out.println("麻雀唱");
}
}抽象类 vs 接口
对比表
| 特性 | 抽象类 | 接口 |
|---|---|---|
| 关键字 | abstract class | interface |
| 实例化 | 不能 | 不能 |
| 方法 | 可以有抽象方法和普通方法 | 只能有抽象方法(Java 8+ 可以有默认方法) |
| 变量 | 可以有各种变量 | 只能是常量(public static final) |
| 构造方法 | 可以有 | 不能有 |
| 继承 | 单继承 | 多实现 |
| 访问修饰符 | 可以是任意 | 默认 public |
使用场景
// 抽象类:用于有共同实现的类层次结构
public abstract class Vehicle {
protected String brand;
public Vehicle(String brand) {
this.brand = brand;
}
// 所有车辆都有启动方法
public void start() {
System.out.println(brand + " 启动");
}
// 不同车辆有不同的行驶方式
public abstract void drive();
}
// 接口:用于定义行为契约
public interface Drawable {
void draw();
}
public interface Clickable {
void onClick();
}
// 一个类可以实现多个接口
public class Button implements Drawable, Clickable {
@Override
public void draw() {
System.out.println("绘制按钮");
}
@Override
public void onClick() {
System.out.println("按钮被点击");
}
}实际应用示例
示例1:支付系统
// 支付接口
public interface Payment {
void pay(double amount);
void refund(double amount);
}
// 支付宝支付
public class AlipayPayment implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + " 元");
}
@Override
public void refund(double amount) {
System.out.println("支付宝退款:" + amount + " 元");
}
}
// 微信支付
public class WeChatPayment implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + " 元");
}
@Override
public void refund(double amount) {
System.out.println("微信退款:" + amount + " 元");
}
}
// 使用接口实现多态
public class PaymentService {
private Payment payment;
public PaymentService(Payment payment) {
this.payment = payment;
}
public void processPayment(double amount) {
payment.pay(amount);
}
}示例2:图形绘制系统
// 可绘制接口
public interface Drawable {
void draw();
double getArea();
}
// 抽象图形类
public abstract class Shape implements Drawable {
protected String color;
public Shape(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
// 圆形
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public void draw() {
System.out.println("绘制圆形,颜色:" + color + ",半径:" + radius);
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
// 矩形
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制矩形,颜色:" + color + ",宽:" + width + ",高:" + height);
}
@Override
public double getArea() {
return width * height;
}
}总结
接口和抽象类都是实现抽象和多态的重要机制:
- 抽象类:用于有共同实现的类层次结构,单继承
- 接口:用于定义行为契约,多实现
- 选择原则:
- 需要定义模板方法时使用抽象类
- 需要定义行为契约时使用接口
- 需要多继承时使用接口
掌握接口和抽象类可以编写更加灵活和可扩展的代码。
相关链接: