Java 学习42:抽象

一、抽象的概念

抽象是一种通过创建简化的模型,来分离 "做什么" 与 "如何做" 的软件设计思想。

Java通过抽象类和接口来实现抽象:

  • 抽象类(Abstract Class):使用 abstract 关键字声明。
  • 接口(Interface):使用 interface 关键字声明。

二、抽象类

1. 抽象类的概念

抽象类是一种用于表示抽象概念的类,它不能被实例化,只能被继承。抽象类通过抽象方法强制子类实现特定行为,同时通过具体方法让子类共享共同行为,在规范性与复用性之间取得平衡。

2. 抽象类的要点

  • 抽象类不能被实例化,因为它代表的是不完整的抽象概念。
  • 抽象类用于被其他类继承。
  • 子类继承抽象类后,必须实现所有的抽象方法,否则该子类也必须声明为抽象类。
  • 抽象类可以包含构造方法,这些构造方法在子类实例化时被调用。
  • 抽象类还可以包含成员变量、成员方法、静态变量和静态方法。

3. 代码示例

java 复制代码
abstract class Animal {
    // 成员变量
    protected String name;
    private static int animalCount = 0; // 静态变量(第5点)
    
    // 构造方法
    public Animal(String name) {
        this.name = name;
        animalCount++;
    }
    
    // 抽象方法
    public abstract void makeSound();
    
    // 具体方法
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
    
    // 静态方法
    public static int getAnimalCount() {
        return animalCount;
    }
}

// 子类必须实现所有抽象方法
class Dog extends Animal {
    // 调用父类构造方法
    public Dog(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + "汪汪叫");
    }
}

// 测试
public class Main {
    public static void main(String[] args) {
        // Animal animal = new Animal("抽象动物"); // 编译错误,抽象类不能被实例化
        Animal dog = new Dog("小黑"); 
        dog.makeSound();
        dog.sleep();
        System.out.println("动物数量: " + Animal.getAnimalCount());
    }
}

三、接口

1. 接口的概念

接口不代表一类事物,而是代表一种规则,是对行为能力的抽象。

实际上,接口定义了一个类必须实现的方法集合。这些方法在接口中没有具体的实现,必须由实现该接口的类来实现。一个类可以实现多个接口。

2. 接口的要点

  • 接口定义方法契约,实现类必须提供这些方法的具体实现。
  • 一个类可以实现多个接口,获得多种行为能力。
  • 接口中的方法默认是 public abstract 的。
  • 接口主要用于定义对象的能力和角色,而非 is-a 关系。

3. 代码示例

java 复制代码
// 定义能力接口
interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

// 不同的类实现相同接口
class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟飞行");
    }
}

class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("鸭子飞行");
    }

    @Override
    public void swim() {
        System.out.println("鸭子游泳");
    }
}

// 使用接口实现多态
public class Test {
    public static void makeItFly(Flyable flyable) {
        flyable.fly(); // 不关心具体类型,只关心飞行能力
    }

    public static void makeItSwim(Swimmable swimmable) {
        swimmable.swim();
    }

    public static void main(String[] args) {
        // 创建不同类型的对象
        Bird sparrow = new Bird();
        Duck donald = new Duck();

        makeItFly(sparrow);
        makeItFly(donald);
        makeItSwim(donald);
    }
}

四、抽象类与接口应用场景对比

使用抽象类:

  • 需要一个共同的基类,部分方法需要在子类中实现,部分方法已经有具体实现。
  • 需要包含成员变量和构造方法,维护一定的状态。

使用接口:

  • 需要定义一个公共的协议或契约,方法的具体实现由不同的类负责。
  • 需要一个类实现多个不同的方法集合。
相关推荐
薛定猫AI8 分钟前
【深度解析】DeepSeek Harness:可插拔智能体运行时如何连接大模型与真实计算机
java·运维·网络
rannn_11114 分钟前
【力扣hot100】回溯专题|全排列、子集、字母组合、组合总和、括号生成、单词搜索、分割回文串、N皇后
java·算法·leetcode·回溯
nxb55634 分钟前
云原生:控制器
java·开发语言·云原生
咖啡八杯44 分钟前
统一返回对象设计:AjaxResult 与 R 的取舍
java·spring boot·框架·若依·返回值
小手cool2 小时前
JSON.parseObject 返回 List 时不能强制转换的解决方案
java·json·list
凯酱3 小时前
MyBatis 中 OGNL 的使用:从入门到实战
java·tomcat·mybatis
吴声子夜歌9 小时前
Java面试——算法
java·算法·面试
evans在进步9 小时前
LeetCode 64:最小路径和——Java 原地动态规划详解
java·leetcode·动态规划
凤山老林10 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端
博傅11 小时前
Spring 核心原理
java·后端·spring