Java面向对象程序设计——类与对象
一、先给一道例题在学生管理系统中我们需要存储和处理学生的基本信息例如姓名、学号、年龄和成绩。如果使用基本类型变量逐个存储代码会非常冗余且难以维护。请用Java面向对象的思想设计一个学生信息管理系统要求如下设计一个Student类包含学号id、姓名name、年龄age和成绩score四个私有属性。提供无参构造方法和带参构造方法用于创建学生对象。为每个属性提供对应的getter和setter方法。在Student类中定义一个showInfo()方法用于输出学生的完整信息。编写测试类创建3个学生对象将它们存入数组并遍历数组输出所有学生的信息。-5-9二、解题思路2.1 类与对象的核心概念类是Java面向对象程序设计的核心概念之一。类可以被理解为一种“蓝图”或“模板”它定义了某一类事物所共有的属性数据和行为方法。例如现实世界中的“学生”这个概念是一个抽象的说法它描述了学生应该具有学号、姓名、年龄等特征以及学习、考试等行为——这就是“类”的概念。对象则是根据这个“蓝图”实际创建出来的具体实例。例如“学号为2024001、姓名为张三、年龄18岁的那个具体学生”就是一个对象。类是抽象的、静态的而对象是具体的、动态的。类是创建对象的模板对象是类的具体表现。2.2 为什么要使用类与对象在面向对象编程出现之前程序开发主要使用面向过程的方式数据和操作数据的函数是分离的。这种方式在小型程序中尚可应对但随着软件规模的增长代码会变得越来越难以维护和扩展。类与对象的引入解决了这个问题它带来了以下优势数据封装将数据和操作数据的方法绑定在一起形成一个整体信息隐藏通过访问修饰符如private将内部实现细节隐藏起来只暴露必要的接口代码复用通过创建多个对象可以重复使用同一个类的定义符合人类思维用计算机语言模拟现实世界的事物及其关系更直观、易理解2.3 类的设计步骤设计一个类通常遵循以下步骤定义类名使用class关键字类名通常采用大驼峰命名法如Student、BankAccount定义属性声明类的成员变量描述对象的状态特征通常使用private修饰定义构造方法用于创建对象时初始化属性方法名与类名相同没有返回值类型定义getter和setter方法提供对外部访问私有属性的安全通道体现封装性定义其他业务方法根据实际需求定义类的行为功能-5-9三、代码实现与逐行解释3.1 完整代码java复制下载/** * 学生类 - 定义学生的属性和行为 * 这是面向对象程序设计的核心将数据属性和操作方法封装在一起 */ class Student { // -------------------- 私有属性封装的核心-------------------- // 属性使用private修饰外部无法直接访问必须通过getter/setter方法操作 private int id; // 学号 private String name; // 姓名 private int age; // 年龄 private double score; // 成绩 // -------------------- 构造方法 -------------------- /** * 无参构造方法 * 当使用new Student()时调用创建对象后各属性为默认值 * 注意如果在类中定义了有参构造建议仍然保留无参构造因为很多框架如Spring依赖它 */ public Student() { System.out.println(调用了无参构造方法); } /** * 带参构造方法构造方法重载 * 当使用new Student(2024001, 张三, 18, 95.5)时调用一步完成对象的创建和初始化 * param id 学号 * param name 姓名 * param age 年龄 * param score 成绩 */ public Student(int id, String name, int age, double score) { this.id id; // this.id表示当前对象的id属性id是参数 this.name name; this.age age; this.score score; System.out.println(调用了带参构造方法 name); } // -------------------- Getter和Setter方法封装的安全通道-------------------- /** * 获取学号 * return 学号 */ public int getId() { return id; } /** * 设置学号 * param id 学号 */ public void setId(int id) { this.id id; } public String getName() { return name; } /** * 设置姓名 * 可以在此方法中添加数据校验逻辑体现封装的业务规则控制能力 * param name 姓名 */ public void setName(String name) { // 示例可以在这里添加姓名不能为空的校验 if (name null || name.trim().isEmpty()) { System.out.println(姓名不能为空); return; } this.name name; } public int getAge() { return age; } /** * 设置年龄 * 在setter方法中加入业务校验确保数据合法性 * param age 年龄应在0-120之间 */ public void setAge(int age) { if (age 0 || age 120) { System.out.println(年龄应在0-120之间); return; } this.age age; } public double getScore() { return score; } /** * 设置成绩 * param score 成绩应在0-100之间 */ public void setScore(double score) { if (score 0 || score 100) { System.out.println(成绩应在0-100之间); return; } this.score score; } // -------------------- 业务方法 -------------------- /** * 展示学生信息 * 将对象的内部状态以格式化的形式输出 */ public void showInfo() { System.out.println(学号 id 姓名 name 年龄 age 成绩 score); } /** * 判断学生是否及格 * return 成绩60返回true否则返回false */ public boolean isPass() { return score 60; } /** * 根据成绩返回等级 * return 等级A/B/C/D/F */ public String getGrade() { if (score 90) { return A; } else if (score 80) { return B; } else if (score 70) { return C; } else if (score 60) { return D; } else { return F; } } } /** * 测试类 - 演示类与对象的创建和使用 * 面向对象编程的三大步骤 * 1. 定义类已完成→ 2. 创建对象 → 3. 调用方法 */ public class ClassAndObjectDemo { public static void main(String[] args) { // -------------------- 方式一使用无参构造 setter方法 -------------------- System.out.println( 方式一无参构造 setter ); Student stu1 new Student(); // 创建对象调用无参构造 stu1.setId(2024001); // 通过setter方法设置属性 stu1.setName(张三); stu1.setAge(18); stu1.setScore(95.5); stu1.showInfo(); // 调用业务方法 // -------------------- 方式二使用带参构造一步完成 -------------------- System.out.println(\n 方式二带参构造 ); Student stu2 new Student(2024002, 李四, 19, 82.0); stu2.showInfo(); System.out.println(是否及格 (stu2.isPass() ? 是 : 否)); System.out.println(成绩等级 stu2.getGrade()); Student stu3 new Student(2024003, 王五, 20, 57.5); stu3.showInfo(); System.out.println(是否及格 (stu3.isPass() ? 是 : 否)); System.out.println(成绩等级 stu3.getGrade()); // -------------------- 对象数组的使用 -------------------- System.out.println(\n 学生对象数组 ); // 声明并创建学生对象数组长度为3 Student[] students new Student[3]; students[0] stu1; // 将已创建的对象存入数组 students[1] stu2; students[2] stu3; // 遍历数组输出所有学生信息 System.out.println(所有学生信息如下); for (int i 0; i students.length; i) { System.out.print(第 (i 1) 位学生); students[i].showInfo(); } // -------------------- 增强for循环遍历 -------------------- System.out.println(\n 增强for循环遍历 ); for (Student s : students) { s.showInfo(); } } }运行结果text复制下载 方式一无参构造 setter 调用了无参构造方法 学号2024001姓名张三年龄18成绩95.5 方式二带参构造 调用了带参构造方法李四 学号2024002姓名李四年龄19成绩82.0 是否及格是 成绩等级B 调用了带参构造方法王五 学号2024003姓名王五年龄20成绩57.5 是否及格否 成绩等级F 学生对象数组 所有学生信息如下 第1位学生学号2024001姓名张三年龄18成绩95.5 第2位学生学号2024002姓名李四年龄19成绩82.0 第3位学生学号2024003姓名王五年龄20成绩57.5 增强for循环遍历 学号2024001姓名张三年龄18成绩95.5 学号2024002姓名李四年龄19成绩82.0 学号2024003姓名王五年龄20成绩57.53.2 逐行代码解释① 类的定义与属性声明java复制下载class Student { private int id; private String name; private int age; private double score; }class关键字用于定义一个类Student是类名遵循大驼峰命名法private是访问修饰符表示这些属性只能在当前类内部被访问外部无法直接读取或修改这种将属性隐藏起来的做法就是封装它保护了数据的完整性和安全性② 构造方法java复制下载public Student() { System.out.println(调用了无参构造方法); } public Student(int id, String name, int age, double score) { this.id id; this.name name; this.age age; this.score score; }构造方法是创建对象的入口方法名必须与类名完全相同且没有返回值类型void也不行无参构造在没有自定义构造方法时由编译器自动提供但如果手动添加了有参构造编译器不再提供无参构造建议手动保留this关键字用于区分成员变量和参数——当成员变量名和参数名相同时this.id指的是当前对象的id属性而id指的是传入的参数-9③ Setter方法中的业务校验java复制下载public void setName(String name) { if (name null || name.trim().isEmpty()) { System.out.println(姓名不能为空); return; } this.name name; }Setter方法不仅仅是简单的赋值还可以加入业务逻辑验证这样做的好处是数据验证逻辑集中在一处避免在多个调用处重复编写校验代码如果以后校验规则发生变化只需要修改这一个方法即可——这正是封装带来的维护性优势④ 对象数组java复制下载Student[] students new Student[3]; students[0] stu1;对象数组的声明与基本类型数组类似类名[] 数组名 new 类名[长度]与基本类型数组不同对象数组的每个位置存储的是对象的引用即对象在内存中的地址而不是对象本身创建数组后需要将已经创建的对象存入数组然后才能使用⑤ 增强for循环for-eachjava复制下载for (Student s : students) { s.showInfo(); }增强for循环是Java 5引入的语法糖专门用于遍历数组和集合语法for (元素类型 变量名 : 数组/集合)每次循环变量s会依次指向数组中的每一个元素代码更加简洁、不易出错-5四、总结通过以上学生类的设计与使用我们可以总结出以下几个核心要点类与对象的本质关系类是对象的“蓝图”或“模板”定义了对象应该具备的属性和行为对象是根据类创建出来的具体实例一个类可以创建无数个对象类是静态的概念存在于代码层面对象是动态的概念存在于运行时内存中创建对象的标准流程声明对象引用类名 对象名;实例化对象对象名 new 类名();new关键字在堆内存中分配空间合并写法类名 对象名 new 类名();类的核心组成部分及作用属性成员变量描述对象的状态特征通常设为private构造方法创建对象时的初始化入口方法名与类名相同无返回值getter/setter方法对外访问私有属性的安全通道可在此添加业务校验逻辑业务方法定义对象的具体行为功能如showInfo、isPass等封装带来的核心价值数据安全性通过private隐藏内部数据外部无法随意篡改数据合法性在setter方法中加入验证逻辑确保对象始终处于合法状态降低耦合度外部只依赖方法不依赖内部实现细节提高可维护性修改内部实现时不影响外部调用代码对象数组的要点对象数组存储的是对象的引用地址不是对象本身先创建数组再创建对象并存入最后才能使用遍历对象数组时注意处理可能存在的null元素命名规范建议类名大驼峰命名法如Student、BankAccount变量名/方法名小驼峰命名法如studentName、showInfo常量名全大写下划线如MAX_SCORE五、更多练习题目推荐以下是可以直接访问的Java类与对象相关练习题请复制链接后自行替换[colon]为:[dot]为.https://www.luogu.com.cn/problem/P5740https://www.luogu.com.cn/problem/P5741https://www.luogu.com.cn/problem/P5742https://blog.csdn.net/2401_87890252/article/details/152521736https://blog.csdn.net/2501_91241024/article/details/149905735https://blog.csdn.net/m0_63792223/article/details/129464959以上洛谷题目都是经典的面向对象练习题P5740要求封装学生类并找出总分最高的学生P5741要求实现学生之间的相似度比较P5742则需要计算综合评分并判断等级-3-6。练习建议可以尝试在Student类中增加更多属性如班级、电话并扩展相应的业务方法如修改密码、计算平均分等进一步熟悉类与对象的设计流程。