abstract 关键字

概述

abstract 关键字用于声明抽象类和抽象方法。

  • 抽象类不能被实例化,只能被继承
  • 抽象方法只有声明没有实现,必须在子类中实现

语法格式

抽象类

public abstract class ClassName {
    // 类体
}

抽象方法

public abstract returnType methodName(parameters);

使用规则

  1. 抽象类规则

    • 不能被实例化
    • 可以包含抽象方法和普通方法
    • 可以包含构造器、成员变量、静态方法
    • 如果类包含抽象方法,类必须声明为abstract
  2. 抽象方法规则

    • 只能在抽象类或接口中声明
    • 不能有方法体
    • 子类必须实现所有抽象方法(除非子类也是抽象类)
    • 不能是private、static、final或synchronized

代码示例

基本用法

// 抽象类
abstract class Animal {
    protected String name;

    // 构造器
    public Animal(String name) {
        this.name = name;
    }

    // 普通方法
    public void sleep() {
        System.out.println(name + " 正在睡觉");
    }

    // 抽象方法
    public abstract void makeSound();
    public abstract void move();
}

// 具体类继承抽象类
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " 汪汪汪");
    }

    @Override
    public void move() {
        System.out.println(name + " 奔跑");
    }
}

class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " 喵喵喵");
    }

    @Override
    public void move() {
        System.out.println(name + " 悄悄走");
    }
}

public class AbstractExample {
    public static void main(String[] args) {
        // Animal animal = new Animal("动物"); // 错误:抽象类不能实例化

        Dog dog = new Dog("旺财");
        dog.sleep();     // 输出:旺财 正在睡觉
        dog.makeSound(); // 输出:旺财 汪汪汪
        dog.move();      // 输出:旺财 奔跑

        Cat cat = new Cat("咪咪");
        cat.sleep();     // 输出:咪咪 正在睡觉
        cat.makeSound(); // 输出:咪咪 喵喵喵
        cat.move();      // 输出:咪咪 悄悄走
    }
}

图形绘制示例

// 抽象图形类
abstract class Shape {
    protected String color;

    public Shape(String color) {
        this.color = color;
    }

    // 普通方法
    public void setColor(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    // 抽象方法
    public abstract double getArea();
    public abstract double getPerimeter();
    public abstract void draw();
}

// 圆形类
class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }

    @Override
    public void draw() {
        System.out.println("绘制" + color + "的圆形,半径:" + radius);
    }
}

// 矩形类
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 double getArea() {
        return width * height;
    }

    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }

    @Override
    public void draw() {
        System.out.println("绘制" + color + "的矩形,宽:" + width + ",高:" + height);
    }
}

public class ShapeExample {
    public static void main(String[] args) {
        Shape[] shapes = {
            new Circle("红色", 5.0),
            new Rectangle("蓝色", 4.0, 6.0)
        };

        for (Shape shape : shapes) {
            shape.draw();
            System.out.println("面积:" + shape.getArea());
            System.out.println("周长:" + shape.getPerimeter());
            System.out.println("---");
        }
    }
}

模板方法模式

// 抽象数据处理类
abstract class DataProcessor {

    // 模板方法 - 定义处理流程
    public final void processData() {
        loadData();
        validateData();
        transformData();
        saveData();
        cleanup();
    }

    // 具体方法
    private void loadData() {
        System.out.println("加载数据...");
    }

    private void cleanup() {
        System.out.println("清理资源...");
    }

    // 抽象方法 - 由子类实现
    protected abstract void validateData();
    protected abstract void transformData();
    protected abstract void saveData();
}

// XML数据处理器
class XMLDataProcessor extends DataProcessor {
    @Override
    protected void validateData() {
        System.out.println("验证XML数据格式");
    }

    @Override
    protected void transformData() {
        System.out.println("转换XML数据");
    }

    @Override
    protected void saveData() {
        System.out.println("保存XML数据到数据库");
    }
}

// JSON数据处理器
class JSONDataProcessor extends DataProcessor {
    @Override
    protected void validateData() {
        System.out.println("验证JSON数据格式");
    }

    @Override
    protected void transformData() {
        System.out.println("转换JSON数据");
    }

    @Override
    protected void saveData() {
        System.out.println("保存JSON数据到文件");
    }
}

public class TemplateMethodExample {
    public static void main(String[] args) {
        DataProcessor xmlProcessor = new XMLDataProcessor();
        xmlProcessor.processData();

        System.out.println();

        DataProcessor jsonProcessor = new JSONDataProcessor();
        jsonProcessor.processData();
    }
}

最佳实践

  1. 合理使用抽象类

    • 当多个类有相同的代码时,使用抽象类提取公共部分
    • 当需要为子类提供默认实现时,使用抽象类
  2. 抽象方法设计

    • 抽象方法应该表示必须由子类实现的核心功能
    • 方法名要清晰表达意图
  3. 构造器设计

    • 为抽象类提供protected构造器
    • 在构造器中进行必要的初始化

注意事项

  1. 实例化限制

    // 错误示例
    abstract class AbstractClass {
        public void method() { }
    }
    
    // AbstractClass obj = new AbstractClass(); // 编译错误
    
  2. 方法修饰符冲突

    abstract class Example {
        // 以下声明都是错误的:
        // private abstract void method1();    // abstract不能是private
        // static abstract void method2();     // abstract不能是static
        // final abstract void method3();      // abstract不能是final
    }
    
  3. 继承要求

    abstract class Parent {
        public abstract void abstractMethod();
    }
    
    // 子类必须实现所有抽象方法
    class Child extends Parent {
        @Override
        public void abstractMethod() {
            // 必须提供实现
        }
    }
    

与接口的区别

特性 abstract类 interface
实例化 不能实例化 不能实例化
继承数量 单继承 多实现
方法类型 抽象方法+普通方法 抽象方法+default方法
成员变量 任意修饰符 public static final
构造器 可以有 不能有
访问修饰符 任意 public

abstract关键字是Java面向对象编程中重要的概念,它提供了代码复用和多态的基础,是实现设计模式的重要工具。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 16:25:54

results matching ""

    No results matching ""