杰瑞科技汇

java abstract 方法

  1. 什么是抽象方法?
  2. 抽象方法的语法和规则
  3. 为什么需要抽象方法?(核心作用)
  4. 抽象类 和抽象方法的关系
  5. 代码示例
  6. 关键要点总结

什么是抽象方法?

抽象方法就是一个没有具体实现(没有方法体)的方法

java abstract 方法-图1
(图片来源网络,侵删)

它只定义了方法的签名(方法名、参数列表、返回类型),但告诉所有继承它的子类:“你必须实现我,但我不知道你具体要怎么做”。

你可以把它想象成一个“合同”或“模板”中的条款,规定了必须要有某个功能,但没有规定这个功能的具体实现细节。


抽象方法的语法和规则

抽象方法的定义非常简单,只需要在普通方法声明前加上 abstract 关键字,并且去掉方法体的大括号 ,直接用分号

语法:

java abstract 方法-图2
(图片来源网络,侵删)
[访问修饰符] abstract 返回类型 方法名(参数列表);

示例:

public abstract void draw(); // 没有参数,没有返回值
public abstract double calculateArea(); // 返回一个 double 值
protected abstract String getName(int id); // 带有参数

重要规则:

  • 没有方法体:这是最核心的特征,绝对不能像这样写 public abstract void draw() { ... },这是错误的。
  • 必须存在于抽象类中:一个非抽象的普通类不能包含抽象方法,如果一个类中包含了至少一个抽象方法,那么这个类必须被声明为 abstract
  • 不能是 privatefinal
    • 不能是 private:因为抽象方法必须被子类实现,而 private 方法无法被子类继承和访问。
    • 不能是 final:因为 final 方法不能被重写,而抽象方法的本质就是要求子类去重写(实现)它。

为什么需要抽象方法?(核心作用)

抽象方法是实现多态模板方法设计模式 的基石,它的主要作用有:

a) 强制子类提供具体实现

这是最直接的作用,当你定义一个“通用”概念时,形状”(Shape),你知道所有形状都有“绘制”(draw)这个行为,但你无法在“形状”这个层面上写出绘制代码,因为圆形、方形的绘制方式完全不同。

java abstract 方法-图3
(图片来源网络,侵删)

通过在 Shape 类中将 draw() 声明为抽象方法,你就强制了任何继承自 Shape 的具体子类(如 Circle, Square必须提供它们自己的 draw() 实现,否则,子类将无法通过编译。

b) 实现多态

这使得我们可以用一种统一的方式来处理不同的对象。

假设我们有以下类结构: Shape (抽象类) -> Circle, Square (具体子类)

我们可以在代码中这样写:

Shape myShape1 = new Circle();
Shape myShape2 = new Square();
myShape1.draw(); // 调用的是 Circle 的 draw() 方法
myShape2.draw(); // 调用的是 Square 的 draw() 方法

尽管 myShape1myShape2 的声明类型都是 Shape,但它们在运行时会根据实际的对象类型(CircleSquare)来调用正确的 draw() 方法,这就是多态,而抽象方法是实现这种“约定式”多态的关键。

c) 定义模板/契约

抽象方法和抽象类共同构成了一个“模板”,抽象类定义了所有子类共有的属性和部分方法(非抽象方法),而抽象方法则定义了子类必须实现的“契约”,这保证了所有子类都具有一组一致的行为接口,使得整个系统更加规范和易于维护。


抽象类 和抽象方法的关系

这两者密不可分:

  • 包含关系:如果一个类中包含了至少一个抽象方法,那么这个类必须被声明为 abstract 类。
  • 独立存在:一个抽象类不一定必须包含抽象方法,它也可以没有抽象方法,但这样声明它为 abstract 通常是为了防止它被直接实例化,只允许创建其子类的对象。

抽象类的特点:

  1. 不能被实例化:你不能像 new Shape() 这样创建抽象类的对象,它只能作为父类被继承。
  2. 可以包含构造方法:虽然不能被实例化,但抽象类可以有构造方法,这个构造方法会在创建子类对象时被调用(通过 super())。
  3. 可以包含成员变量、普通方法、静态方法:除了抽象方法,抽象类和普通类没有太大区别,可以包含任何成员。
  4. 可以包含抽象方法:这是它最核心的特征。

代码示例

下面是一个经典的“形状”例子,可以很好地展示抽象方法的使用。

步骤 1: 定义抽象父类 Shape

// Shape.java
public abstract class Shape {
    // 成员变量
    private String color;
    // 构造方法
    public Shape(String color) {
        this.color = color;
    }
    // 抽象方法:没有方法体,子类必须实现
    public abstract double calculateArea();
    // 普通方法:有具体实现,子类可以选择重写
    public void displayInfo() {
        System.out.println("This is a shape with color: " + color);
    }
    // Getter
    public String getColor() {
        return color;
    }
}

步骤 2: 创建具体子类 CircleSquare

// Circle.java
public class Circle extends Shape {
    private double radius;
    public Circle(String color, double radius) {
        // 调用父类的构造方法
        super(color);
        this.radius = radius;
    }
    // 必须实现父类的抽象方法
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
    // 可以选择重写父类的普通方法
    @Override
    public void displayInfo() {
        System.out.println("This is a Circle with radius: " + radius);
    }
}
// Square.java
public class Square extends Shape {
    private double side;
    public Square(String color, double side) {
        super(color);
        this.side = side;
    }
    // 必须实现父类的抽象方法
    @Override
    public double calculateArea() {
        return side * side;
    }
}

步骤 3: 在主程序中测试多态

// Main.java
public class Main {
    public static void main(String[] args) {
        // 创建具体子类的对象
        Shape circle = new Circle("Red", 5.0);
        Shape square = new Square("Blue", 4.0);
        // 使用父类类型的引用来调用方法
        // 这体现了多态
        System.out.println("--- Circle ---");
        circle.displayInfo(); // 调用 Circle 重写的 displayInfo()
        System.out.println("Area: " + circle.calculateArea()); // 调用 Circle 的 calculateArea()
        System.out.println("\n--- Square ---");
        square.displayInfo(); // 调用 Square 重写的 displayInfo()
        System.out.println("Area: " + square.calculateArea()); // 调用 Square 的 calculateArea()
    }
}

输出结果:

--- Circle ---
This is a Circle with radius: 5.0
Area: 78.53981633974483
--- Square ---
This is a Square with side: 4.0
Area: 16.0

main 方法可以看出,我们用 Shape 类型的引用 circlesquare 来操作对象,但程序在运行时能正确地调用到各自子类中实现的 calculateArea()displayInfo() 方法,这就是抽象方法和多态的威力。


关键要点总结

特性 描述
定义 只有方法签名(声明),没有方法体 的方法。
关键字 使用 abstract 修饰。
所在类 必须存在于 abstract 类中。
实例化 抽象方法本身不能被调用,它所在的抽象类也不能被实例化。
子类要求 任何继承抽象类的具体子类必须实现(重写)其所有的抽象方法。
访问修饰符 不能是 privatefinal
核心目的 强制子类实现特定功能。
为多态提供基础,实现“统一接口,多种实现”。
定义模板,规范子类的行为。

希望这个详细的解释能帮助你完全理解 Java 中的 abstract 方法!

分享:
扫描分享到社交APP
上一篇
下一篇