上一篇我们掌握了Java数组与字符串能通过数组存储多个数据、通过字符串处理文本信息完成了简单的综合实战学生信息管理。但这些代码依然是“面向过程”的——我们关注的是“步骤”比如“先录入学生信息、再打印、再求平均分”一步步执行。而Java是一门面向对象的编程语言面向对象编程OOP是Java的核心思想能让代码更具复用性、扩展性和可维护性也是实际开发中最常用的编程思想。面向对象编程的核心是“类与对象”我们通过“类”来抽象事物的共性通过“对象”来具体实现事物的特性再通过“封装”隐藏事物的细节、暴露必要的功能让代码更安全、更简洁。本篇文章将从基础入手手把手教你理解类与对象的概念、区别与联系掌握成员变量、成员方法、构造方法的用法吃透封装特性拆解新手高频易错点比如类与对象混淆、构造方法误用结合实战案例带你从“面向过程”正式转向“面向对象”编程。核心目标理解面向对象编程思想掌握类与对象的定义、创建与使用熟练运用成员变量、成员方法、构造方法理解封装特性并能实现封装能独立完成简单的面向对象实战案例比如学生类、手机类规避常见坑为后续学习继承、多态筑牢基础。一、前置认知面向过程 vs 面向对象核心区别在学习面向对象之前我们先明确“面向过程”和“面向对象”的核心区别理解为什么需要面向对象编程——它能解决面向过程编程的痛点代码复用性差、扩展性差、维护困难。1.1 面向过程编程POP核心思想关注步骤一步一步实现功能。把一个复杂的问题拆解成多个简单的步骤每个步骤用一段代码实现最终将所有步骤串联起来完成功能。举例实现“学生成绩管理”面向过程步骤1定义数组存储学生姓名和成绩步骤2录入学生姓名和成绩写一段录入代码步骤3打印学生信息写一段打印代码步骤4求平均成绩写一段计算代码步骤5查找学生信息写一段查找代码。特点代码是“线性的”步骤清晰但复用性差比如另一个项目需要录入学生信息无法直接复用之前的代码、扩展性差比如要增加“修改成绩”功能需要修改大量原有代码、维护困难代码杂乱一个步骤出错整个流程都受影响。1.2 面向对象编程OOP核心思想关注“对象”通过对象实现功能。把一个复杂的问题拆解成多个“对象”每个对象负责一个具体的功能对象之间通过交互完成整个需求。对象是由“类”创建的类是对象的“模板”封装了对象的属性特征和方法行为。举例实现“学生成绩管理”面向对象定义“学生类Student”封装学生的属性姓名、成绩和方法录入信息、展示信息定义“成绩管理类StudentManager”封装管理功能打印所有学生、求平均分、查找学生创建学生对象、成绩管理对象通过对象调用方法完成所有功能。特点代码是“模块化的”每个对象负责自己的功能复用性强学生类可以在多个项目中复用、扩展性强增加“修改成绩”功能只需给学生类增加一个方法、维护简单每个模块独立出错后只需修改对应对象的代码。1.3 核心区别总结新手必记编程思想核心关注点特点举例面向过程POP步骤、流程简单直接复用性差、扩展性差用数组循环实现学生成绩管理面向对象OOP对象、模块复用性强、扩展性强、易维护用Student类Manager类实现学生成绩管理核心结论面向对象是对面向过程的优化更适合复杂项目的开发也是Java的核心思想后续我们所有的开发都会围绕“类与对象”展开。二、核心概念类与对象重中之重类与对象是面向对象编程的基础二者是“模板与实例”的关系必须彻底理解二者的区别与联系否则后续学习会非常困难。2.1 类Class对象的模板类是抽象的是对一类事物的“共性描述”包含事物的“属性”特征和“方法”行为。比如“学生”是一个类它的属性有姓名、年龄、成绩方法有学习、考试、展示信息“手机”是一个类它的属性有品牌、型号、价格方法有打电话、发消息、拍照。类的核心作用定义事物的属性和方法作为创建对象的“模板”——一个类可以创建多个对象每个对象都拥有类中定义的所有属性和方法但属性的值可以不同。2.2 对象Object类的实例对象是具体的是根据类创建出来的“具体实例”拥有类中定义的所有属性和方法且每个对象的属性都有具体的值。比如根据“学生类”创建出“张三”“李四”两个对象张三的姓名是“张三”、成绩是90李四的姓名是“李四”、成绩是85二者都有“学习”“展示信息”的方法但属性值不同。对象的核心作用具体实现类中定义的功能是代码执行的最小单元。2.3 类与对象的关系类比理解新手必懂用生活中的例子类比快速理解类与对象的关系类 汽车设计图模板定义了汽车的属性品牌、颜色、排量和方法行驶、刹车是抽象的不能直接使用对象 具体的汽车实例根据设计图制造出来的具体汽车有具体的品牌丰田、颜色白色、排量1.5T能执行行驶、刹车的方法是具体的可以直接使用关系一个设计图类可以制造出多辆汽车对象所有汽车都拥有设计图中定义的属性和方法但具体属性值不同。2.4 类的定义格式固定写法必须掌握Java中类的定义有固定格式包含类名、属性成员变量、方法成员方法三部分语法格式如下// 类的定义格式 public class 类名 { // 1. 成员变量属性定义类的特征直接写在类中方法外 数据类型 变量名1; 数据类型 变量名2; ... // 2. 成员方法行为定义类的功能写在类中 public 返回值类型 方法名(参数列表) { 方法体; // 具体功能实现 return 返回值; // 若返回值类型是void可省略return } }关键说明类名遵循“大驼峰命名法”首字母大写后续每个单词首字母也大写比如Student、Phone、StudentManager不能用关键字比如class、int成员变量直接定义在类中、方法外无需初始化系统会赋默认值和数组、基本数据类型默认值一致成员方法和之前学的方法类似但无需加static关键字加static的是静态方法后续讲解直接写在类中。2.5 对象的创建与使用核心操作对象是根据类创建的创建对象的过程称为“实例化”使用对象的核心是“调用成员变量”和“调用成员方法”。1对象的创建格式实例化对象// 格式类名 对象名 new 类名(); 类名 对象名 new 类名(); // 示例根据Student类创建对象 Student zhangsan new Student();说明new关键字的作用是“在内存中为对象分配空间”创建对象后对象名zhangsan就指向内存中的对象通过对象名就能操作对象的属性和方法。2对象的使用调用成员变量和成员方法// 1. 调用成员变量对象名.成员变量名 对象名.成员变量名 值; // 给成员变量赋值 对象名.成员变量名; // 获取成员变量的值 // 2. 调用成员方法对象名.方法名(参数); 对象名.方法名(参数);实战案例定义学生类Student创建对象并使用// 1. 定义学生类Student public class Student { // 成员变量属性姓名、年龄、成绩 String name; int age; double score; // 成员方法行为展示学生信息 public void showInfo() { System.out.println(姓名 name 年龄 age 成绩 score); } // 成员方法学习无返回值无参数 public void study() { System.out.println(name 正在学习Java); } // 成员方法考试有参数有返回值 public double exam(String subject) { System.out.println(name 参加 subject 考试); return score; // 返回成绩 } } // 2. 测试类包含main方法创建对象并使用 public class StudentTest { public static void main(String[] args) { // 第一步创建学生对象实例化对象 Student zhangsan new Student(); // 第二步给对象的成员变量赋值 zhangsan.name 张三; zhangsan.age 18; zhangsan.score 90.5; // 第三步调用对象的成员方法 zhangsan.showInfo(); // 调用showInfo方法展示信息 zhangsan.study(); // 调用study方法 double examScore zhangsan.exam(Java); // 调用exam方法接收返回值 System.out.println(考试成绩 examScore); // 再创建一个学生对象同一个类可以创建多个对象 Student lisi new Student(); lisi.name 李四; lisi.age 19; lisi.score 85.0; lisi.showInfo(); lisi.study(); } }运行结果姓名张三年龄18成绩90.5 张三正在学习Java 张三参加Java考试 考试成绩90.5 姓名李四年龄19成绩85.0 李四正在学习Java避坑点1必须先创建对象new 类名()才能调用成员变量和成员方法直接用“类名.成员变量”“类名.方法名”会报错除非是静态属性/方法。避坑点2不同对象的成员变量是独立的修改一个对象的成员变量不会影响另一个对象比如修改zhangsan的namelisi的name不会变。三、类的核心组成成员变量 vs 局部变量新手易混淆在类中我们会遇到两种变量成员变量定义在类中、方法外和局部变量定义在方法中、代码块中二者的作用域、默认值、生命周期都不同是新手最易混淆的知识点之一必须严格区分。3.1 成员变量与局部变量的核心区别区别维度成员变量局部变量定义位置类中、方法外方法中、代码块中比如for循环中默认值有默认值和基本数据类型、引用类型默认值一致无默认值必须先初始化赋值才能使用作用域整个类所有成员方法都能访问仅当前方法/代码块出了方法/代码块就无法访问生命周期和对象一致对象创建成员变量存在对象销毁成员变量消失和方法/代码块一致方法执行局部变量存在方法结束局部变量消失命名冲突不能和类中其他成员变量重名可以和成员变量重名局部变量优先级更高方法中优先使用局部变量实战演示区分成员变量与局部变量public class VariableDemo { // 成员变量类中、方法外 int num1 10; // 有默认值可直接使用也可手动赋值 String str1; // 有默认值null public void test() { // 局部变量方法中 int num2; // 无默认值必须先赋值才能使用 // System.out.println(num2); // 错误未初始化 num2 20; // 初始化局部变量 String str2 局部变量; // 定义时直接初始化 // 局部变量和成员变量重名局部变量优先级更高 int num1 30; System.out.println(局部变量num1 num1); // 输出30使用局部变量 System.out.println(成员变量num1 this.num1); // 输出10用this关键字访问成员变量 // 访问局部变量 System.out.println(局部变量num2 num2); // 输出20 System.out.println(局部变量str2 str2); // 输出局部变量 } public static void main(String[] args) { VariableDemo demo new VariableDemo(); demo.test(); // 访问成员变量通过对象 System.out.println(成员变量num1 demo.num1); // 输出10 System.out.println(成员变量str1 demo.str1); // 输出null // 无法访问局部变量局部变量作用域仅在test方法中 // System.out.println(num2); // 错误找不到变量num2 } }避坑点3局部变量无默认值必须先初始化才能使用成员变量有默认值可直接使用但建议手动赋值避免使用默认值导致逻辑错误。避坑点4当局部变量和成员变量重名时用this关键字访问成员变量this代表当前对象后续详细讲解否则会优先使用局部变量。四、面向对象核心特性封装重点必懂封装是面向对象的三大特性之一另外两个是继承、多态后续讲解核心思想是“隐藏细节暴露接口”——将类的成员变量属性隐藏起来不允许外部直接访问而是通过提供“getter方法”获取属性值和“setter方法”设置属性值来访问和修改属性这样可以控制属性的访问权限避免属性被非法修改让代码更安全、更易维护。4.1 为什么需要封装解决什么问题没有封装的问题外部可以直接访问和修改类的成员变量容易导致非法数据录入破坏数据的安全性。举例无封装的问题public class Student { // 无封装成员变量直接暴露外部可直接修改 String name; int age; double score; public void showInfo() { System.out.println(姓名 name 年龄 age 成绩 score); } } public class Test { public static void main(String[] args) { Student student new Student(); // 外部直接修改成员变量可录入非法数据年龄为负数、成绩超过100 student.age -18; // 非法年龄 student.score 150; // 非法成绩 student.showInfo(); // 输出姓名null年龄-18成绩150数据错误 } }问题外部可以随意修改成员变量没有任何限制导致数据错误这就是没有封装的弊端。而封装可以解决这个问题通过控制属性的访问权限过滤非法数据。4.2 封装的实现步骤固定写法封装的实现分为3步核心是“用private修饰成员变量提供getter/setter方法”用private关键字修饰成员变量将成员变量隐藏起来外部无法直接访问private表示“私有”仅当前类可访问提供getter方法用于获取成员变量的值方法名格式get成员变量名首字母大写返回值类型和成员变量一致无参数提供setter方法用于设置成员变量的值方法名格式set成员变量名首字母大写无返回值void有一个参数和成员变量类型一致可在方法中添加逻辑过滤非法数据。4.3 封装实战案例规范写法对Student类进行封装控制年龄和成绩的合法性年龄≥0成绩0~100public class Student { // 第一步用private修饰成员变量隐藏细节 private String name; private int age; private double score; // 第二步提供getter方法获取属性值 public String getName() { return name; } // 第三步提供setter方法设置属性值添加逻辑过滤 public void setName(String name) { this.name name; // this.name指成员变量name指参数 } public int getAge() { return age; } // 设置年龄过滤非法数据年龄≥0 public void setAge(int age) { if (age 0) { this.age age; // 合法数据赋值 } else { System.out.println(年龄非法请输入≥0的数字); // 非法数据提示 } } public double getScore() { return score; } // 设置成绩过滤非法数据0≤成绩≤100 public void setScore(double score) { if (score 0 score 100) { this.score score; } else { System.out.println(成绩非法请输入0~100之间的数字); } } // 成员方法展示学生信息 public void showInfo() { System.out.println(姓名 getName() 年龄 getAge() 成绩 getScore()); } } // 测试类 public class StudentTest { public static void main(String[] args) { Student student new Student(); // 无法直接访问private修饰的成员变量报错 // student.name 张三; // 错误name是private外部无法访问 // 通过setter方法设置属性值会过滤非法数据 student.setName(张三); student.setAge(-18); // 输出年龄非法请输入≥0的数字不赋值 student.setAge(18); // 合法赋值 student.setScore(150); // 输出成绩非法请输入0~100之间的数字不赋值 student.setScore(90.5); // 合法赋值 // 通过getter方法获取属性值 System.out.println(学生姓名 student.getName()); // 输出张三 System.out.println(学生年龄 student.getAge()); // 输出18 // 调用方法展示信息 student.showInfo(); // 输出姓名张三年龄18成绩90.5 } }运行结果年龄非法请输入≥0的数字 成绩非法请输入0~100之间的数字 学生姓名张三 学生年龄18 姓名张三年龄18成绩90.5核心优势通过封装外部无法直接修改成员变量只能通过setter方法设置且setter方法中可以添加逻辑过滤非法数据保证了数据的安全性同时隐藏了类的内部细节外部只需调用getter/setter方法无需关心内部实现降低了代码的耦合度。4.4 封装的常见易错点忘记用private修饰成员变量依然让成员变量暴露无法实现封装的效果getter/setter方法命名错误比如getAge写成getage、setAge写成setage首字母未大写导致无法正常调用setter方法中未添加逻辑过滤虽然用了private修饰但setter方法直接赋值没有过滤非法数据失去了封装的核心意义混淆this关键字在setter/getter方法中未用this区分成员变量和参数导致赋值失败比如setName(String name) { name name; }无法给成员变量赋值。五、对象的初始化构造方法重点必懂我们之前创建对象后需要通过setter方法给成员变量赋值步骤比较繁琐。而构造方法的核心作用是“创建对象时直接给成员变量赋值”简化对象的初始化过程无需再手动调用setter方法。构造方法是类的特殊方法创建对象时new 类名()会自动调用无需手动调用。5.1 构造方法的定义格式固定写法// 构造方法格式 public 类名(参数列表) { 方法体; // 给成员变量赋值 }关键说明核心特点必须记住构造方法的方法名必须和类名完全一致大小写也要一致不能有返回值类型即使是void也不能写构造方法没有返回值也不能写return语句除非是return;表示结束方法创建对象时会自动调用构造方法new 类名() 就是调用构造方法如果类中没有手动定义构造方法Java会自动提供一个“无参构造方法”默认构造方法无参数、无方法体如果类中手动定义了构造方法Java就不会再提供默认的无参构造方法建议手动添加无参构造方法避免报错。5.2 构造方法的分类2种常用1无参构造方法无参数作用创建对象时给成员变量赋默认值和系统默认值一致或手动给成员变量赋初始值。// 无参构造方法方法名和类名一致无参数无返回值 public Student() { // 可手动给成员变量赋初始值 this.name 未知姓名; this.age 0; this.score 0.0; }2有参构造方法有参数作用创建对象时直接给成员变量赋具体的值无需再调用setter方法简化初始化步骤。// 有参构造方法参数对应成员变量 public Student(String name, int age, double score) { // 用this关键字区分成员变量和参数给成员变量赋值 this.name name; this.age age; this.score score; }5.3 构造方法实战案例规范写法给Student类添加无参构造方法和有参构造方法简化对象初始化public class Student { // 私有成员变量封装 private String name; private int age; private double score; // 1. 无参构造方法手动添加避免默认构造方法被覆盖 public Student() { System.out.println(无参构造方法被调用创建对象); // 给成员变量赋初始值 this.name 未知姓名; this.age 0; this.score 0.0; } // 2. 有参构造方法3个参数直接赋值 public Student(String name, int age, double score) { System.out.println(有参构造方法被调用创建对象); // 过滤非法数据和setter方法逻辑一致 this.name name; if (age 0) { this.age age; } else { this.age 0; System.out.println(年龄非法默认赋值为0); } if (score 0 score 100) { this.score score; } else { this.score 0.0; System.out.println(成绩非法默认赋值为0.0); } } // getter/setter方法封装必备 public String getName() { return name; } public void setName(String name) { this.name name; } public int getAge() { return age; } public void setAge(int age) { if (age 0) { this.age age; } else { System.out.println(年龄非法); } } public double getScore() { return score; } public void setScore(double score) { if (score 0 score 100) { this.score score; } else { System.out.println(成绩非法); } } // 展示信息方法 public void showInfo() { System.out.println(姓名 name 年龄 age 成绩 score); } } // 测试类 public class StudentTest { public static void main(String[] args) { // 1. 调用无参构造方法创建对象 Student student1 new Student(); student1.showInfo(); // 输出姓名未知姓名年龄0成绩0.0 // 2. 调用有参构造方法创建对象合法数据 Student student2 new Student(张三, 18, 90.5); student2.showInfo(); // 输出姓名张三年龄18成绩90.5 // 3. 调用有参构造方法创建对象非法数据 Student student3 new Student(李四, -19, 150); student3.showInfo(); // 输出年龄非法默认赋值为0成绩非法默认赋值为0.0姓名李四年龄0成绩0.0 } }运行结果无参构造方法被调用创建对象 姓名未知姓名年龄0成绩0.0 有参构造方法被调用创建对象 姓名张三年龄18成绩90.5 有参构造方法被调用创建对象 年龄非法默认赋值为0 成绩非法默认赋值为0.0 姓名李四年龄0成绩0.0六、新手高频易错点总结必看避坑指南类与对象混淆误以为类可以直接使用忘记创建对象new 类名()就调用成员变量/方法成员变量与局部变量混淆局部变量未初始化就使用或混淆二者的作用域封装实现不规范未用private修饰成员变量或未提供getter/setter方法或setter方法未过滤非法数据构造方法误用构造方法名与类名不一致、添加返回值类型、未添加无参构造方法this关键字误用未用this区分成员变量和参数导致赋值失败静态方法与成员方法混淆在成员方法中调用静态方法可以但在静态方法中调用成员方法/变量错误静态方法不依赖对象无法访问成员变量/方法。七、总结与下期预告本篇文章重点讲解了Java面向对象的基础核心——类与对象、封装、构造方法这是面向对象编程的基石也是后续学习继承、多态、接口的前提。我们理解了面向对象与面向过程的区别掌握了类的定义、对象的创建与使用学会了用封装保护数据安全用构造方法简化对象初始化同时通过综合实战案例感受了面向对象编程的优势复用性强、扩展性强。动手练习建议1. 定义一个Phone类封装品牌、型号、价格提供构造方法、getter/setter方法、打电话/发消息方法2. 完善学生成绩管理案例增加“修改学生成绩”“删除学生信息”功能3. 定义一个Person类封装姓名、年龄实现封装和构造方法测试类中创建多个对象并使用。