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

Java面向对象入门:从C语言到类和对象

Java面向对象入门:从C语言到类和对象

1. 引入:为什么需要面向对象?

1.1 C语言写代码的痛点

假设你要写一个学生管理系统,需要存储学生的姓名、年龄、分数:

// C语言的方式charname[50];intage;intscore;// 如果要存多个学生,需要多个数组charnames[100][50];intages[100];intscores[100];// 添加一个学生,要同时操作三个数组voidaddStudent(char*name,intage,intscore){// 维护三个数组,很容易出错}

问题:数据和操作数据的函数是分离的,代码一多就容易乱。

1.2 面向对象的解决方案

把相关的数据和操作打包在一起,形成一个整体:

// Java的方式:一个Student类搞定classStudent{Stringname;intage;intscore;}

这就是面向对象的核心理念:把数据和对数据的操作封装在一起


2. 类和对象:从图纸到房子

2.1 类是什么?

是一张蓝图,描述了某类事物的共同特征。

比如"学生"这类事物:

  • 有什么属性:姓名、年龄、分数
  • 有什么行为:学习、考试、休息
classStudent{// 属性(成员变量)Stringname;intage;intscore;// 行为(成员方法)voidstudy(){System.out.println(name+"正在学习");}}

2.2 对象是什么?

对象是根据类这张蓝图创建出来的具体实例。

就像根据一张图纸可以盖很多房子:

// 创建对象Students1=newStudent();s1.name="张三";s1.age=18;s1.study();// 输出:张三正在学习Students2=newStudent();s2.name="李四";s2.age=19;s2.study();// 输出:李四正在学习

类和对象的关系

  • 类是抽象的、概念的(学生)
  • 对象是具体的、实际的(张三、李四)

3. 封装:为什么要加private?

3.1 没有封装的问题

直接暴露属性会出问题:

Students=newStudent();s.age=-5;// 年龄怎么能是负数?但没有报错

3.2 用private保护数据

classStudent{privateStringname;privateintage;// 私有:只有本类能访问privateintscore;// 通过getter获取publicintgetAge(){returnage;}// 通过setter设置(可以加逻辑判断)publicvoidsetAge(intage){if(age>=0&&age<=150){this.age=age;}else{System.out.println("年龄不合法");}}}

封装的三个层次

  1. 属性私有化:用private修饰
  2. 提供getter/setter:控制访问方式
  3. 在setter中添加逻辑:保护数据合法性

3.3 对比C语言

维度C语言Java封装
数据保护全靠程序员自觉编译器强制检查
修改数据直接改结构体成员必须通过setter
添加逻辑要改所有使用的地方只改setter方法

4. this关键字:谁调用我,我就是谁

4.1 什么时候用this?

成员变量局部变量名字冲突时:

classStudent{privateintage;// 成员变量publicvoidsetAge(intage){// 局部变量也叫ageage=age;// 问题:到底是谁赋值给谁?}}

上面的代码分不清哪个是成员变量,哪个是参数。用this解决:

publicvoidsetAge(intage){this.age=age;// this.age是成员变量,age是参数}

4.2 this的内存原理

this代表当前正在调用方法的那个对象

Students1=newStudent();s1.setAge(18);// 执行setAge时,this就是s1Students2=newStudent();s2.setAge(20);// 执行setAge时,this就是s2

4.3 this的三种用法

用法示例说明
区分成员和局部this.age = age最常用
调用本类构造方法this(参数)必须在第一行
返回当前对象return this链式调用

5. 构造方法:创建对象时自动执行

5.1 什么是构造方法?

构造方法是创建对象时自动调用的特殊方法:

classStudent{privateStringname;privateintage;// 无参构造publicStudent(){System.out.println("对象被创建了");}// 有参构造publicStudent(Stringname,intage){this.name=name;this.age=age;}}

5.2 构造方法的特点

特点说明
方法名必须和类名相同写错了就是普通方法
没有返回值类型连void都不能写
自动调用new的时候自动执行
可以重载可以写多个构造方法

5.3 注意事项

// 写了有参构造,最好手动写无参构造classStudent{publicStudent(Stringname){// 有参构造}// 如果不写无参构造,new Student()会报错}

原因:如果写了有参构造,系统就不会再提供默认的无参构造了。


6. JavaBean:一种规范

JavaBean就是按照一定规范编写的类

6.1 三条规范

  1. 成员变量私有化:用private
  2. 提供无参构造方法:方便框架反射创建对象
  3. 提供getter和setter:统一访问方式

6.2 标准写法

publicclassStudent{// 1. 私有成员变量privateStringname;privateintage;// 2. 无参构造publicStudent(){}// 3. 有参构造(可选,但建议写上)publicStudent(Stringname,intage){this.name=name;this.age=age;}// 4. getter/setterpublicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}}

6.3 IDEA快捷生成

不用手写,用快捷键:

  • Mac:Command + N
  • Windows:Alt + Insert

选择Getter and SetterConstructor即可自动生成。


7. 内存图:理解栈和堆

7.1 Java的内存分区

区域存储内容特点
局部变量、方法调用方法执行完就释放
对象、成员变量GC自动回收
方法区类信息、静态变量类加载时存入

7.2 基本数据类型 vs 引用数据类型

inta=10;// 基本类型:值直接存在栈里Students=newStudent();// 引用类型:栈里存地址,对象在堆里

图解

栈 堆 ┌─────┐ ┌─────────────┐ │ a=10│ │ Student对象 │ ├─────┤ │ name=null │ │ s │──────────────→│ age=0 │ └─────┘ └─────────────┘

7.3 三种情况的对象内存图

情况1:一个对象

Students=newStudent();// 栈:s存地址 → 堆:Student对象

情况2:两个对象

Students1=newStudent();Students2=newStudent();// 栈:s1和s2存不同地址 → 堆:两个独立对象

情况3:两个引用指向同一个对象

Students1=newStudent();Students2=s1;// s2和s1指向同一个对象// 修改s1的属性,s2也会变

8. 成员变量 vs 局部变量

维度成员变量局部变量
定义位置类中、方法外方法内或参数
作用域整个类方法内
默认值有(int=0,引用=null)没有,必须初始化
内存位置堆(对象里)
生命周期随对象创建和销毁随方法调用和结束
classStudent{privateintage;// 成员变量:有默认值0publicvoidstudy(){inthour;// 局部变量:没有默认值,必须先赋值hour=2;// 必须赋值才能用System.out.println("学了"+hour+"小时");}}

9. 综合训练:文字版格斗游戏

9.1 需求

创建两个角色,互相攻击,直到一方血量归零。

9.2 代码实现

publicclassCharacter{privateStringname;//属性privateintblood;publicCharacter(){}//构造方法publicCharacter(Stringname,intblood){this.name=name;this.blood=blood;}publicvoidsetName(Stringname){//set,get 函数this.name=name;}publicStringgetName(){returnname;}publicintgetBlood(){returnblood;}publicvoidsetBlood(intblood){this.blood=blood;}publicvoidattack(Characterch1){//行为Randomr=newRandom();intattack=r.nextInt(20)+1;intbloodLive=ch1.getBlood()-attack;if(bloodLive<0){bloodLive=0;}ch1.setBlood(bloodLive);System.out.println(this.name+"打了"+ch1.name+attack+"点血量,"+ch1.name+"还剩"+bloodLive+"血量");}publicvoiddied(){System.out.println(this.getName()+"被打死了.");}}importjava.util.Scanner;publicclassdraft{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);Characterch1=newCharacter();Characterch2=newCharacter();System.out.println("输入两个挑战者的名字:");ch1.setName(sc.nextLine());ch2.setName(sc.nextLine());System.out.println("输入两个挑战者的血量:");ch1.setBlood(sc.nextInt());ch2.setBlood(sc.nextInt());while(ch1.getBlood()>0&&ch2.getBlood()>0){ch1.attack(ch2);if(ch2.getBlood()<=0){ch2.died();break;}ch2.attack(ch1);if(ch1.getBlood()<=0){ch1.died();break;}}}}

10. 对象数组练习

10.1 基本对象数组

// 创建对象数组Student[]students=newStudent[3];// 给每个位置赋值students[0]=newStudent("张三",18);students[1]=newStudent("李四",19);students[2]=newStudent("王五",20);// 遍历for(inti=0;i<students.length;i++){System.out.println(students[i].getName());}

10.2 操作(添加、删除、统计)

// 统计年龄大于18的学生intcount=0;for(Students:students){if(s.getAge()>18){count++;}}// 删除指定位置(把后面的往前移)for(inti=index;i<size-1;i++){students[i]=students[i+1];}students[size-1]=null;size--;

11. 总结对比:C vs Java

维度C语言Java
组织方式函数 + 结构体类(数据+方法打包)
数据保护private + getter/setter
内存管理malloc/free手动new + 自动GC
构造初始化手动写init函数构造方法自动调用
数组长度需自己维护arr.length
http://www.cnnetsun.cn/news/1719415.html

相关文章:

  • OpenHarmony4.0屏幕旋转避坑手册:RK3566开发板实战经验分享
  • 2026 AI Agent 爆发元年:OpenClaw v2026.4.2(The Lobster)Windows 深度部署与全路径避坑指南
  • 魔兽争霸3显示优化完全指南:从问题诊断到深度优化
  • MogFace模型Matlab仿真验证:快速原型设计与算法对比
  • 智能音箱‘耳背’怎么办?拆解AEC(回声消除)在语音唤醒和打断场景下的核心挑战
  • 万字长文实战教程:用Python从零构建一个具备工具调用能力的Agent
  • AEM项目VSCode自动编译ts
  • Windows安卓APK安装工具:跨平台应用的高效解决方案
  • DAMOYOLO-S目标检测模型Java开发实战:SpringBoot微服务集成指南
  • Kandinsky-5.0-I2V-Lite-5s Web界面深度解析:非聊天式专业图生视频工具设计
  • Cursor Pro功能真的只能付费使用吗?探索开源工具如何突破AI编程助手限制
  • 如何用BilibiliDown解锁B站无损音频:探索专业级音乐下载的新路径
  • 从OFF到TXT:ModelNet40/10数据集格式转换与预处理实战
  • 教育资源获取的高效解决方案:开源工具助力电子教材下载
  • 3步解锁百度网盘全速下载:给Mac用户的效率提升指南
  • 靶机通关1--nullbytes
  • 喜马拉雅音频下载器:解决VIP内容离线保存的技术方案
  • 3步精通SMAPI部署:星露谷物语模组加载器完整实战指南
  • Xshell远程管理Cosmos-Reason1-7B服务器配置指南
  • 2026年出游不用愁!为你强力推荐超靠谱的地陪平台
  • 告别风扇噪音!4步掌握Windows智能风扇控制系统
  • 从ChatMessage.proto到压测报告:一个完整IM消息系统的JMeter WebSocket压测实战复盘
  • 颠覆式聊天记录管理:3步构建个人数据主权中心
  • Postman便携版:如何在Windows上实现零安装API开发环境?
  • 2026年,口碑超棒的三角洲俱乐部究竟如何为你保驾护航?
  • Windows系统运行安卓应用的无缝解决方案:APK Installer使用指南
  • 如何高效解决腾讯游戏卡顿问题:ACE-Guard资源限制器完整方案
  • OpenClaw调试技巧:Qwen2.5-VL-7B多模态任务排错手册
  • I2CKeyPad:基于PCF8574的轻量级矩阵键盘Arduino库
  • 突破式API开发:Postman便携版如何重塑你的工作流