当前位置: 首页 > news >正文

面向对象编程基础:从方法论到实践的全面解析

面向对象编程基础:从方法论到实践的全面解析

一、面向对象:重构编程思维的方法论

在狂神说 Java 第 60-62 集课程中,我们正式进入面向对象编程(Object-Oriented Programming-OOP)的核心模块。作为 Java 语言的核心思想,面向对象编程通过封装、继承、多态三大特性,将复杂问题拆解为可复用的对象模型,显著提升代码的可维护性与扩展性。

面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

本文将结合课程内容,系统解析面向对象的基础概念、方法定义与调用机制。

二、面向对象核心概念:从过程到对象的思维转变

1. 面向对象 vs 面向过程

维度面向过程(POP)面向对象(OOP)
核心思想以 “过程” 为中心,关注步骤实现以 “对象” 为中心,关注数据与行为封装
典型场景简单算法、工具类开发复杂业务系统、大型项目架构
代码结构函数驱动,数据与操作分离类驱动,数据与操作绑定
  • 面向过程思想
    • 步骤清晰简单,第一步做什么,第二步做什么…
    • 面对过程适合处理一些较为简单的问题
  • 面向对象思想
    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

2. 类与对象:OOP 的基础单元

  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。
类(Class)—— 对象的模板
// 学生类:封装“学生”的属性与行为
public class Student {
    // 属性(数据抽象:学生的状态)
    String name;
    int age;
    
    // 方法(行为抽象:学生的动作)
    public void study() {
        System.out.println(name + "正在学习");
    }
}
对象(Object)—— 类的实例
// 创建对象:通过new关键字实例化类
Student student = new Student();
student.name = "张三"; // 操作属性
student.study(); // 调用方法
package com.oop;

public class Demo02 {
    //静态方法 static
    public static void main(String[] args) {
        // Student.say();

        //非静态方法
        // 实例化这个类
        //对象类型 对象名 = 对象值
        Student student = new Student();
        student.say();
    }
    //遵循一个原则:被static修饰的内容会跟随类的加载而加载,所以静态化的内容可以不用实例化就直接调用,同时两个静态方法之间也可以互相调用
    //和类一起加载的
    public static void a(){
        //b();
    }
    //类实例化 之后才存在
    public void b(){

    }
}

3. 面向对象三大特性(初步认知)

特性核心作用示例场景
封装将数据(属性)与操作(方法)绑定,隐藏实现细节银行账户类:余额私有,通过公开方法存取
继承子类复用父类代码,实现 “IS-A” 关系学生类继承人类,复用姓名、年龄属性
多态父类引用指向子类对象,同一方法不同实现动物类的 “叫声” 方法,猫和狗不同实现

三、方法定义:类的行为建模

1. 方法的完整定义

[修饰符] 返回类型 方法名([参数列表]) [throws 异常类型] {
    // 方法体:具体逻辑实现
     业务代码;
    return 结果; // 若返回类型为void,可省略return
}
package com.oop;

import java.io.FileNotFoundException;
import java.io.IOException;

//Demo01  类
public class Demo01 {
    //main  方法
    public static void main(String[] args) {

    }
    /*
    修饰符  返回值类型  方法名(。。。){
    //方法体
    return 返回值;
    }
     */
    //return 结束方法,返回一个结果
    public String sayhello(){
        return "Hello World";
    }
    public void print(){
        return;
    }
    public int max(int a,int b){
        return a>b?a:b;//三元运算符
    }
    //数组下标越界:Arrayindexoutofbounds
    public void readFile(String file) throws IOException {

    }
}

2. 核心要素解析

要素说明示例代码
修饰符public/private/protected等访问控制,static/final等特性public static void main(String[] args)
参数列表支持基本类型、对象引用、可变参数(...void print(String... messages)
返回类型必须与return语句类型匹配,void表示无返回int sum(int a, int b) { return a + b; }

3. 构造方法:对象初始化

public class Person {
    String name;
    
    // 无参构造
    public Person() {
        name = "匿名";
    }
    
    // 有参构造
    public Person(String name) {
        this.name = name; // this关键字指向当前对象
    }
}

四、方法调用:对象交互的桥梁

1. 实例方法 vs 静态方法

实例方法(对象级方法:需对象调用)
  • 调用前提:必须通过类的实例(对象)调用
  • 内存模型:方法属于对象,每个对象独立拥有方法副本(非静态方法)
Student student = new Student();
student.study(); // 通过对象引用调用
静态方法(类级方法:类名直接调用)
  • 调用方式:直接通过类名调用,无需创建对象
  • 适用场景:工具类方法(如Math.sqrt())、全局通用逻辑
public class MathUtils {
    public static int add(int a, int b) {
        return a + b;
    }
}

// 调用方式
int result = MathUtils.add(1, 2);
实参形参
package com.oop;

public class Demo03 {
    public static void main(String[] args) {

        new Demo03().add(2,3);
//实际参数和形式参数的类型要对应!
        int add = Demo03.add(3, 4);
        System.out.println(add);
    }
    public static int add(int a,int b){
        return a+b;
    }
}
===============================================
package com.oop;
//学生类
public class Student {
    // //静态方法
    // public static void say(){
    //     System.out.println("学生说话了");
    //非静态方法
    public void say(){
            System.out.println("学生说话了");
        }
    // }
}
值传递
package com.oop;
//值传递
public class Demo04 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);
        Demo04.change(a);
        System.out.println(a);
    }

    //返回值为空
    public static void change(int a){
        a = 10;
    }
}

引用传递
package com.oop;
//引用传递:对象,本质还是值传递
public class Demo05 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);//null
        Demo05.change(person);
        System.out.println(person.name);//秦疆
    }
    public static void change(Person person){
        //person是一个对象,指向的是--->Person person = new Person();这是一个具体的人,可以改变属性
        person.name = "秦疆";
    }
}
//定义了一个Person类,有一个属性:name
class Person{
    String name;//null
}

2. 方法重载(Overload)在 OOP 中的应用

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public double add(double a, double b) {
        return a + b; // 重载方法,参数类型不同
    }
}

3. this 关键字的核心作用

  • 指代当前对象,区分成员变量与局部变量
  • 在构造方法中调用其他构造方法(this(参数)
public class Car {
    String color;
    
    public Car() {
        this("黑色"); // 调用Car(String color)构造方法
    }
    
    public Car(String color) {
        this.color = color;
    }
}

五、面向对象设计原则(基础篇)

1. 单一职责原则(SRP)

  • 核心:一个类 / 方法只负责一项职责
// 反模式:一个类承担多个职责
public class UserService {
    void registerUser(); // 注册逻辑
    void sendEmail(); // 邮件发送逻辑(应拆分)
}

// 推荐做法:职责分离
public class UserService { /* 注册逻辑 */ }
public class EmailService { /* 邮件发送逻辑 */ }

2. 封装最佳实践

  • 属性私有:用private修饰属性,禁止外部直接访问

  • 方法公开:通过public方法提供访问接口,控制数据修改逻辑

public class BankAccount {
    private double balance; // 私有属性账户余额私有
    
    public double getBalance() { // 公开访问方法
        return balance;
    }
    
    public void setBalance(double balance) { // 控制修改逻辑
        if (balance >= 0) {
            this.balance = balance;// 校验余额合法性
        }
    }
}

七、高频面试题解析

1. 类与对象的关系是什么?

  • 是抽象的模板(如 “人类”),定义了属性(姓名、年龄)和方法(说话、行走)
  • 对象是具体的实例(如 “张三” 这个人),拥有类的属性值和行为能力
  • 关系:类是对象的类型,对象是类的实例,一个类可以创建多个对象,每个对象独立拥有属性值
    • 示例:Student类是模板,student1student2是具体实例

2. 静态方法为什么不能直接访问实例成员?

  • 内存分配:静态方法属于类(加载时分配内存),实例成员属于对象(实例化后分配)
  • 访问逻辑:静态方法执行时,可能尚未创建对象,无法确定访问哪个实例的成员
  • 正确做法:若需访问实例成员,需通过对象引用调用
    • 类比:静态方法是 “班级规则”,实例成员是 “学生个体特征”

3. 构造方法可以重载吗?

  • 可以重载:通过参数列表不同(类型、顺序、数量)实现

  • 示例:

    public Person() { ... } // 无参构造
    public Person(String name) { ... } // 有参构造(重载)
    
  • 注意事项

    • 构造方法无返回类型,方法名必须与类名一致
    • 若不定义构造方法,编译器自动生成无参构造(若定义了有参构造,需手动添加无参构造)
    • this()必须是构造方法的第一行代码,用于调用其他构造方法

4. 实例方法与静态方法的使用场景如何区分?

场景实例方法静态方法
操作对象状态必须(需访问 / 修改对象属性)无需(不依赖对象状态)
工具类方法不适用(需创建对象)适用(如Arrays.sort()
共享逻辑每个对象独立(如Student.study()全局唯一(如Math.PI

5. 什么是方法重载?判断重载的依据是什么?

  • 定义:同一类中,方法名相同但参数列表不同的多个方法

  • 判断依据

    • 参数类型、顺序、数量必须至少有一个不同
    • 返回类型、修饰符不影响重载(仅参数列表决定)
    // 合法重载
    public void print(int num);  
    public void print(String str);  
    

八、学习资源推荐

  1. Java 面向对象官方教程
  2. 狂神说 Java 课程
  3. 设计模式入门指南

九、总结与互动

核心知识图谱

面向对象编程
├─ 核心概念:类、对象、封装、继承、多态
├─ 方法定义:修饰符、参数、构造方法、重载
├─ 方法调用:实例方法(对象调用) vs 静态方法(类名调用)
├─ 设计原则:单一职责、封装数据
└─ 面试核心:类与对象区别、静态方法限制、构造方法重载

实践建议

  1. 从需求抽象类:将现实中的事物(如 “用户”“订单”)映射为 Java 类,先定义属性(状态)再定义方法(行为)
  2. 优先使用封装:所有属性设为private,通过getter/setter控制访问,养成数据校验习惯
  3. 区分方法类型:工具类方法(如计算、日志)用静态方法,与对象状态相关的逻辑用实例方法

相关文章:

  • 【BEPU V1物理】BEPUphysics v1 入门指南 汉化笔记#1
  • JavaScript 基础语法系统学习笔记
  • 使用MPI-IO并行读写HDF5文件
  • 操作系统简要概述
  • 深入解析 Android 图形系统:Canvas、Skia、OpenGL 与 SurfaceFlinger 的协作
  • Vue 3 自定义指令
  • Mac配置开发环境
  • 【Hadoop入门】Hadoop生态之Pig简介
  • 一体化关节模组核心芯片(人形机器人)
  • 双指针、滑动窗口
  • QScrCpy源码解析(4)获取手机端数据知识补充
  • 文章记单词 | 第30篇(六级)
  • 帆软 FCA-FineBI 认证:迈向商业智能专家之路
  • 文章记单词 | 第28篇(六级)
  • ROS第十梯:ROS+VSCode+Python+C++利用launch自启动节点
  • 几何与游标
  • 大模型时代的“数字共生”:AI如何塑造人类社会的新范式
  • Python中try用法、内置异常类型与自定义异常类型拓展
  • # 基于OpenCV与Dlib的人脸融合技术实现
  • 程序化广告行业(81/89):行业术语解析与日常交流词汇指南
  • 普京确定俄乌谈判俄方代表团名单
  • 夜读丨读《汉书》一得
  • 4月企业新发放贷款利率处于历史低位
  • 菲律宾中期选举初步结果出炉,杜特尔特家族多人赢得地方选举
  • 排污染黑海水后用沙土覆盖黑泥?汕尾环保部门:非欲盖弥彰
  • 明查|印度空军“又有一架战机被巴基斯坦击落,飞行员被俘”?