六、java面向对象

2 阅读6分钟

Java 面向对象(OOP)超详细完整版

包含:核心思想、封装、继承、多态、权限修饰符、抽象类、接口、static/final、内部类、企业真实坑点,全程按企业开发标准整理。


一、面向对象核心思想

  1. 一切皆对象,以对象为基本单位组织代码
  2. 三大特征:封装、继承、多态
  3. 面向过程:关注怎么做(步骤)
  4. 面向对象:关注谁来做(对象)

二、类与对象

1. 类

  • 一类事物的模板、图纸
  • 包含:属性(成员变量)+ 行为(成员方法)

2. 对象

  • 类的实例
  • 通过 new 类名() 创建
  • 存储在堆内存

3. 成员变量 vs 局部变量

区别成员变量局部变量
位置类内方法外方法内/语句内
内存
生命周期随对象创建/销毁随方法进栈出栈
默认值有默认值无,必须赋值
修饰符可使用权限修饰符不能用权限修饰符

三、封装(Encapsulation)

核心思想

对外隐藏实现细节,对外提供公共访问方式

实现步骤

  1. 成员变量 private 私有化
  2. 提供 getXxx() / setXxx()
  3. 方法内做合法性校验

好处

  • 安全可控
  • 便于维护
  • 降低耦合
  • 屏蔽复杂实现

企业坑

  • 过度封装:一堆无用 get/set,代码臃肿
  • 不封装:直接 public 变量,外部随意修改导致业务错乱
  • set 方法不做校验,脏数据入库

四、构造方法(Constructor)

特点

  • 方法名与类名完全一致
  • 无返回值类型,连 void 都没有
  • 创建对象时 new 自动调用
  • 每个类默认有一个无参构造

分类

  • 无参构造
  • 有参构造(快速赋值)
  • 全参构造(企业常用)

语法

public class User {
    private String name;

    // 无参
    public User() {}

    // 有参
    public User(String name) {
        this.name = name;
    }
}

企业坑

  1. 写了有参构造,无参构造消失,导致反射/框架报错
  2. 构造方法内做耗时操作(查询数据库、网络请求)
  3. 构造方法抛异常,对象创建失败
  4. 循环依赖构造器,死循环

五、this 关键字

作用:

  1. 区分成员变量与局部变量重名
  2. this(...) 调用本类其他构造方法
    • 必须在第一行
    • 只能调用一个
  3. 代表当前对象本身

六、继承(Inheritance)

语法

class 子类 extends 父类 {}

特点

  • Java 是单继承,一个类只能有一个直接父类
  • 可以多层继承
  • 子类继承父类非私有成员(变量、方法)

方法重写(Override)

两同、两小、一大

  • 方法名相同、参数列表相同
  • 返回值类型 ≤ 父类
  • 抛出异常 ≤ 父类
  • 访问权限 ≥ 父类

super 关键字

  • super.xxx 访问父类成员
  • super(...) 调用父类构造
  • 必须在构造第一行

执行顺序(面试必考)

父类静态代码块 → 子类静态代码块 → 父类代码块 → 父类构造 → 子类代码块 → 子类构造

企业坑

  1. 滥用继承,导致层级过深、耦合爆炸
  2. 父类改动,所有子类受影响(雪崩效应)
  3. 重写时不小心写成重载(参数改了)
  4. 子类构造忘记 super(),父类无无参构造时报错
  5. 继承导致权限泄露,破坏封装

七、多态(Polymorphism)

前提

  1. 继承/实现关系
  2. 方法重写
  3. 父类引用指向子类对象
Animal a = new Cat();

编译看左边,运行看右边

  • 编译:能调用什么方法,看父类
  • 运行:方法执行,看子类

成员变量特点

编译看左,运行也看左(变量不具备多态)

向上转型 & 向下转型

  • 向上:自动转(安全)
  • 向下:强制转(可能 ClassCastException
  • 配合 instanceof 判断

企业坑

  1. 强转前不判断 instanceof,直接类型转换异常
  2. 多态下调用成员变量结果不符合预期
  3. 框架大量使用多态,排查问题困难
  4. 静态方法多态无效(静态属于类,不属于对象)

八、权限修饰符(企业开发规范)

修饰符同类同包子类任意位置
private
default
protected
public

企业规范

  • 所有成员变量 private
  • 工具方法 private
  • 对外接口 public
  • 包内复用 default
  • 子类需要用 protected

九、static 关键字(静态)

修饰内容

  • 静态变量(类变量)
  • 静态方法
  • 静态代码块
  • 静态内部类

特点

  • 类加载而加载,优先于对象
  • 全局只有一份
  • 静态方法不能访问非静态成员
  • 静态方法不能用 this/super

静态代码块

static {
    // 类加载时执行,只执行一次
}

企业坑

  1. 静态变量线程不安全,高并发下数据错乱
  2. 静态方法无法被 Spring AOP、事务管理
  3. 静态持有大对象,导致内存泄漏
  4. 滥用静态,代码难以测试、难以扩展

十、final 关键字

作用

  • 修饰类:类不能被继承
  • 修饰方法:方法不能被重写
  • 修饰变量:变量变为常量,只能赋值一次

常量规范

public static final XXX 全大写,下划线分隔

企业坑

  1. final 修饰引用类型,对象内容仍可修改
  2. 接口变量默认 public static final
  3. 过度使用 final 导致代码僵化

十一、代码块

  1. 局部代码块:方法内,限制变量作用域
  2. 构造代码块:类内方法外,每次创建对象执行
  3. 静态代码块:类加载执行一次
  4. 同步代码块:线程安全

十二、抽象类(abstract)

语法

abstract class Animal {
    // 抽象方法:无方法体
    public abstract void eat();
}

规则

  • 抽象类不能实例化
  • 包含抽象方法的类必须是抽象类
  • 抽象类可以有普通方法、变量、构造器
  • 子类必须重写所有抽象方法,否则子类也要抽象

使用场景

模板设计模式,定义规范 + 提供通用逻辑


十三、接口(Interface)

JDK7 及以前

  • 常量:public static final
  • 抽象方法:public abstract

JDK8+

  • 允许默认方法 default
  • 允许静态方法
  • 更像一个能力扩展

implements

class Cat implements Run, Jump {}

接口 vs 抽象类

  • 接口:多实现,侧重能力
  • 抽象类:单继承,侧重模板

企业坑

  1. JDK8 接口默认方法冲突,编译报错
  2. 一个类实现多个接口,方法签名冲突
  3. 接口常量修改,所有实现类需重新编译

十四、内部类

分类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类(企业最常用)

匿名内部类

简化创建实现类/子类对象:

new Thread(new Runnable() {
    @Override
    public void run() {}
}).start();

企业坑

  • 匿名内部类持有外部类引用,容易内存泄漏
  • 大量匿名类导致类文件过多
  • Lambda 出现后基本替代匿名内部类

十五、企业面向对象开发规范

  1. 单一职责:一个类只做一件事
  2. 少用继承,多用组合/接口
  3. 面向接口编程,而非面向实现
  4. 禁止超大类、万能类
  5. 属性私有,对外提供安全访问
  6. 禁止随意使用 static
  7. 方法粒度细化,便于复用与测试

十六、本章高频面试题

  1. 重载与重写的区别
  2. 多态的前提与执行特点
  3. this 和 super 区别
  4. 接口和抽象类区别
  5. static 应用场景与内存
  6. 权限修饰符使用场景
  7. 代码块执行顺序
  8. 为什么 Java 单继承