Java进阶理解纪要

基类、抽象类、接口对比

抽象类和接口有很多类似的地方,它们都属于模板,用于一些基类复用、或者对一些基类进行规范;

区别是,抽象类既有供子类共用的逻辑,也有只能规范、子类自己实现的部分;而接口,则完全只定规范,实现全由其实现类完成;

一、抽象类和基类对比

1、定义与特点

对比项 抽象类 非抽象类
定义 使用 abstract 关键字声明,可以包含抽象方法和具体实现 完全实现所有方法,可以直接实例化
实例化 不能直接实例化,必须通过子类继承并实现抽象方法 可以直接实例化(除非是工具类等设计为不可实例化的类)
方法 可以包含抽象方法(无实现)和具体方法(有实现) 所有方法必须有具体实现(不能有抽象方法)

2、设计目的

抽象类 非抽象类
作为基类,定义部分通用逻辑,强制子类实现特定行为(通过抽象方法)。 - 适合模板方法模式,提供骨架流程。 - 体现"是什么"(is-a)关系,强调继承的层次性 提供完整功能,直接使用。 - 适合作为最终实现或独立组件。 - 强调"能做什么"(行为的具体实现)

3、抽象类及其使用的示例

bash 复制代码
abstract class Animal {
    //抽象方法(无实现)
    abstract void makeSound();
    // 具体方法(有实现)
    void eat() {
        System.out.println("Eating...");
    }
}
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Bark!");
    }
}
// 使用
Animal dog = new Dog(); // 通过子类实例化
dog.makeSound(); // 输出: Bark!
dog.eat();       // 输出: Eating...

3、何时使用?

选择抽象类:

  • 需要定义公共逻辑,但部分行为由子类决定。
  • 强制子类遵循某种规范(如抽象方法)。
  • 例如:InputStream 是抽象类,子类需实现 read()。

选择非抽象类:

  • 功能完整且无需扩展。
  • 不需要强制子类实现任何方法。
  • 例如:String、ArrayList 等工具类。

二、抽象类和接口对比

1、相似之处

特性 抽象类 接口
不能直接实例化 必须被子类继承 必须被类实现
可以定义抽象方法 可以有抽象方法(abstract void foo();) 所有方法默认是抽象的(Java 8 之前)
支持多态 通过子类实现多态 通过实现类实现多态
可以用于代码复用 提供部分实现 Java 8 后支持默认方法(default)

todo:了解接口的默认方法使用场景

2、核心区别

对比项 抽象类 非抽象类
关键字 abstract class interface
继承/实现方式 单继承(Java 是单继承) 多实现(一个类可实现多个接口)
变量 可以包含实例变量(private, protected, public) 只能包含常量(public static final,默认)
构造方法 可以有构造方法(用于子类初始化) 不能有构造方法
方法实现 可以包含具体方法(有实现)和抽象方法 Java 8 前所有方法都是抽象的,Java 8+ 支持 default 和 static 方法
设计目的 部分实现 + 强制子类实现某些方法(模板模式) 定义行为规范(多态、解耦)
使用场景 适用于is-a关系(如 Animal 是 Dog 的父类) 适用于can-do关系(如 Runnable 表示可运行的任务)

3、如何选择

使用抽象类的情况:

  1. 多个子类有公共逻辑,但部分方法需要子类自定义(如 AbstractList 提供部分实现,ArrayList 继承它)。
  2. 需要维护状态(成员变量),而不仅仅是方法定义。
  3. 希望强制子类实现某些方法(如 Animal 的 makeSound() 必须由子类实现)。

使用接口的情况:

  1. 定义行为契约(如 Comparable 表示可比较,Runnable 表示可运行)。

  2. 需要多继承(Java 不支持多继承类,但支持多实现接口)。

  3. 未来可能扩展(接口更灵活,Java 8+ 支持默认方法,不影响已有实现类)。

三、抽象类的经典使用场景------把一些类的父类定为为抽象类

为什么有些父类推荐定义为抽象类?有什么好处?

1、强制子类实现特定行为(规范约束)

抽象类可以定义抽象方法(没有实现的方法),要求所有子类必须实现这些方法。

  • 作用:确保子类遵循统一的规范,避免遗漏关键逻辑。

2、定义部分实现的模板(和第一个是同一种东西,但是它有2个用处)

  • 抽象类可以定义算法骨架,部分步骤由子类实现。
  • 作用:控制流程结构,同时允许子类灵活扩展。

和1是同一种内容,就是父类可以定义抽象方法,子类必须实现,父类定个规范即可,调用时会自动执行子类重写的方法;

但是这个东西,它有1、2两个作用。

3、限制直接实例化(设计安全性)

  • 抽象类不能直接实例化,必须通过子类使用。
  • 作用:防止误用不完整的父类,确保功能由具体子类实现。

4、代码复用(这个不是抽象类作为父类时特有的,是说抽象类也有普通类作为父类时的用处)

  • 抽象类可以包含具体方法(已实现的方法),子类直接复用这些逻辑,无需重复编写。
  • 作用:减少重复代码,提高可维护性。
相关推荐
天若有情6732 小时前
从C++ RefInt到JS Object.defineProperty:吃透响应式监听的本质(学生视角)
开发语言·javascript·c++
liqianpin12 小时前
java进阶1——JVM
java·开发语言·jvm
hsjcjh2 小时前
node.js+npm的环境配置以及添加镜像(保姆级教程)
java
wjs20242 小时前
HTML 音频/视频
开发语言
在荒野的梦想2 小时前
LangChain4j 集成若依单体应用 | 5 大 AI 功能实战:多轮对话、流式输出、RAG 知识库
java·人工智能
我能坚持多久2 小时前
C++入门基础知识
开发语言·c++·学习
枫叶丹42 小时前
【HarmonyOS 6.0】ArkUI 闪控球功能深度解析:从API到实战
开发语言·microsoft·华为·harmonyos
苏渡苇2 小时前
ConcurrentHashMap.computeIfAbsent():高并发下安全初始化的终极方案
java·安全·jdk·高并发·hashmap·concurrent
小白学大数据2 小时前
实战复盘:Python 爬虫破解网站动态加载页面思路
开发语言·爬虫·python