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);
    }
}

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

使用抽象类:

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

使用接口:

  • 需要定义一个公共的协议或契约,方法的具体实现由不同的类负责。
  • 需要一个类实现多个不同的方法集合。
相关推荐
Mr.朱鹏1 小时前
RocketMQ安装与部署指南
java·数据库·spring·oracle·maven·rocketmq·seata
雨中飘荡的记忆1 小时前
Spring表达式详解:SpEL从入门到实战
java·spring
Coder-coco1 小时前
个人健康管理|基于springboot+vue+个人健康管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·mysql·论文
5***26221 小时前
Spring Boot问题总结
java·spring boot·后端
xkroy2 小时前
Spring Boot日志
java·spring boot·后端
n***F8752 小时前
【Spring Boot】SpringBoot自动装配-Import
java·spring boot·后端
〝七夜5692 小时前
JVM内存结构
java·开发语言·jvm
初级炼丹师(爱说实话版)2 小时前
JAVA泛型作用域与静态方法泛型使用笔记
java·开发语言·笔记
盖世英雄酱581362 小时前
Java.lang.Runtime 深度解析
java·后端