08、Java 基础硬核复习:面向对象编程(进阶)的核心逻辑与面试考点
一、核心知识体系:三大板块,构建面向对象的"设计思维"
本章的知识可以归纳为三大板块 :关键字修饰符 (控制成员的"生命周期")、抽象与规范 (定义系统的"骨架")、高级特性(增强代码的"灵活性")。
1. 关键字修饰符:控制成员的"生命周期"
(1)static(静态):类的"全局变量"
- 核心作用:让成员"脱离对象存在",随类的加载而加载(存储在方法区/元空间),被所有对象共享。
- 修饰范围:属性、方法、代码块、内部类。
- 应用场景 :
- 工具类(如
Math,所有方法都是静态的); - 单例模式(确保类仅有一个实例);
- 静态代码块(类加载时执行,用于初始化静态资源,如加载配置文件)。
- 工具类(如
- 案例 :
Circle类的静态属性PI(所有圆共享同一个 π 值)、银行Account类的静态方法getTotalAccounts()(统计所有账户数量)。
(2)final(最终):不可变的"契约"
- 修饰对象 :类(不可继承,如
String)、方法(不可重写,如Object的getClass())、变量(常量,不可重新赋值)。 - 关键点 :
final修饰引用变量时,保证的是地址值不变 (不能指向新对象),但对象内部的属性可以修改(如final Student s = new Student(); s.name = "Tom";合法)。
- 应用场景 :定义常量(如
public static final String APP_NAME = "MyApp")、防止子类破坏父类逻辑(如final方法)。
(3)代码块:对象的"初始化脚本"
- 静态代码块 :类加载时执行1次(用于初始化静态资源),执行顺序优先于非静态代码块。
- 非静态代码块:每次创建对象时执行(用于初始化实例资源),执行顺序在构造方法之前。
- 执行顺序口诀 :先父后子,先静后动(父类静态块 → 子类静态块 → 父类普通块/构造器 → 子类普通块/构造器)。
2. 抽象与规范:定义系统的"骨架"
(1)abstract(抽象类):模板的"骨架"
- 核心特征:包含抽象方法(无实现),无法实例化,必须被子类继承。
- 设计模式 :模板方法模式 (Template Method)------ 定义算法骨架,子类实现细节(如
AbstractServlet的service()方法,子类实现doGet()/doPost())。 - 与普通类的区别:抽象类可以包含具体方法,强调"代码复用"(is-a 关系)。
(2)interface(接口):规范的"契约"
- 核心作用:定义"规范"(如 USB 接口),实现"多重继承"的效果(类可以同时实现多个接口)。
- 新特性(JDK 8/9) :
- JDK 8:默认方法(
default,解决接口升级问题,如List的sort()方法)、静态方法(如Collections.sort()); - JDK 9:私有方法(
private,代码复用,隐藏实现细节)。
- JDK 8:默认方法(
- 与抽象类的区别:接口强调"规范"(has-a/can-do 关系),抽象类强调"代码复用"(is-a 关系)。
3. 高级特性:增强代码的"灵活性"
(1)内部类:对象的"嵌套结构"
- 类型:成员内部类(实例/静态)、局部内部类、匿名内部类(最常用,如事件监听、线程创建)。
- 关键点 :
- 静态内部类不依赖外部类实例(可直接访问外部类静态成员);
- 匿名内部类是 Lambda 表达式的前身(如
new Runnable(){ public void run(){...} })。
(2)枚举(Enum):有限对象的"集合"
- 本质 :特殊的类(继承
Enum,final修饰,构造私有),用于定义有限确定的对象(如Season、员工状态)。 - 应用场景:单例模式(枚举天然线程安全,防反射破坏)、状态管理(如订单状态:待支付、已支付)。
(3)注解(Annotation):元数据的"标记"
- 核心作用 :为代码添加元数据(如
@Override标记重写方法、@Deprecated标记过时方法)。 - 元注解 :
@Target(注解作用范围,如METHOD)、@Retention(注解生命周期,如RUNTIME)。 - 自定义注解 :通过
@interface定义,结合反射使用(如 Spring 的@Autowired)。
(4)包装类(Wrapper Class):基本类型的"对象化"
- 核心作用 :基本数据类型与对象的转换(装箱:
int → Integer,拆箱:Integer → int)。 - 关键点 :
Integer缓存池(-128~127 范围内复用对象,超出范围new新对象),因此Integer a = 127; Integer b = 127; a == b;为true,而Integer c = 128; Integer d = 128; c == d;为false。
二、高频面试考点:必考"死穴",掌握这些=掌握 Java 底层
本章的面试题非常考验对 Java 底层的理解,以下是必考考点:
1. static 的限制:为什么静态方法不能调用非静态成员?
- 答案 :静态成员随类加载存在,此时对象还未创建,非静态成员(属于对象)根本不存在。因此,静态方法中不能使用
this和super(它们都依赖对象)。
2. 类初始化顺序:"先父后子,先静后动"
-
考点:父类静态块 → 子类静态块 → 父类普通块/构造器 → 子类普通块/构造器。
-
示例:
javaclass Parent { static { System.out.println("父类静态块"); } { System.out.println("父类普通块"); } Parent() { System.out.println("父类构造器"); } } class Child extends Parent { static { System.out.println("子类静态块"); } { System.out.println("子类普通块"); } Child() { System.out.println("子类构造器"); } } public class Test { public static void main(String[] args) { new Child(); } } // 输出:父类静态块 → 子类静态块 → 父类普通块 → 父类构造器 → 子类普通块 → 子类构造器
3. 接口 vs 抽象类:什么时候用接口,什么时候用抽象类?
- 答案 :
- 抽象类:强调"代码复用"(is-a 关系,如
Animal是Dog的父类,保留共性方法eat()); - 接口:强调"规范"(has-a/can-do 关系,如
USB接口,任何设备都可以实现它,不管是什么品牌)。
- 抽象类:强调"代码复用"(is-a 关系,如
4. final 修饰引用变量:地址不变,属性可变
- 考点 :
final Student s = new Student(); s.name = "Tom";合法吗? - 答案 :合法。
final保证的是s的地址值不变(不能s = new Student()),但s指向的对象的属性可以修改。
5. 单例模式:手写线程安全的单例
-
考点 :通常考双重检查锁 或静态内部类方式(线程安全且懒加载)。
-
示例(静态内部类):
javapublic class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
6. 包装类的自动装箱/拆箱:== vs equals()
- 考点 :
Integer a = 10; Integer b = 10; a == b;为true(缓存池),Integer c = 128; Integer d = 128; c == d;为false(超出缓存范围)。 - 注意 :基本类型比较用
==(比较值),包装类比较用equals()(比较内容),除非明确知道缓存池范围。
三、学习建议:从"理论"到"实践"的跃迁
- 接口:用"生活例子"理解:比如 USB 接口,任何设备(鼠标、键盘)都可以实现它,不管是什么品牌,这就是"规范"的体现。
- 匿名内部类:多写代码 :比如
new Comparator<Integer>(){ public int compare(Integer o1, Integer o2){ return o1 - o2; } },这是 Lambda 表达式的前身,掌握它有助于理解函数式编程。 - static:搞清楚内存图:静态成员在方法区,非静态成员在堆,所有 static 相关的问题(如多线程安全)就迎刃而解了。
- 单例模式:手写实现:尝试用双重检查锁、静态内部类、枚举三种方式实现单例,理解它们的优缺点。
四、总结:从"造对象"到"设计系统"的跃迁
第08章是 Java 基础的"封神"章节,它将你从"如何创建对象"带入"如何设计系统"的层面。掌握 static、final、抽象类、接口等高阶语法,你就能理解 Spring、MyBatis 等框架的设计思想,也能在面试中轻松应对"Java 基础"的"硬核"问题。
记住,面向对象的核心不是"写代码",而是"设计系统"------这一章,就是教你如何用 Java 的语法,设计出优雅、高效、可扩展的系统。