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

张开发
2026/4/6 10:43:21 15 分钟阅读

分享文章

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 对象是什么对象是根据类这张蓝图创建出来的具体实例。就像根据一张图纸可以盖很多房子// 创建对象Students1newStudent();s1.name张三;s1.age18;s1.study();// 输出张三正在学习Students2newStudent();s2.name李四;s2.age19;s2.study();// 输出李四正在学习类和对象的关系类是抽象的、概念的学生对象是具体的、实际的张三、李四3. 封装为什么要加private3.1 没有封装的问题直接暴露属性会出问题StudentsnewStudent();s.age-5;// 年龄怎么能是负数但没有报错3.2 用private保护数据classStudent{privateStringname;privateintage;// 私有只有本类能访问privateintscore;// 通过getter获取publicintgetAge(){returnage;}// 通过setter设置可以加逻辑判断publicvoidsetAge(intage){if(age0age150){this.ageage;}else{System.out.println(年龄不合法);}}}封装的三个层次属性私有化用private修饰提供getter/setter控制访问方式在setter中添加逻辑保护数据合法性3.3 对比C语言维度C语言Java封装数据保护全靠程序员自觉编译器强制检查修改数据直接改结构体成员必须通过setter添加逻辑要改所有使用的地方只改setter方法4. this关键字谁调用我我就是谁4.1 什么时候用this当成员变量和局部变量名字冲突时classStudent{privateintage;// 成员变量publicvoidsetAge(intage){// 局部变量也叫ageageage;// 问题到底是谁赋值给谁}}上面的代码分不清哪个是成员变量哪个是参数。用this解决publicvoidsetAge(intage){this.ageage;// this.age是成员变量age是参数}4.2 this的内存原理this代表当前正在调用方法的那个对象Students1newStudent();s1.setAge(18);// 执行setAge时this就是s1Students2newStudent();s2.setAge(20);// 执行setAge时this就是s24.3 this的三种用法用法示例说明区分成员和局部this.age age最常用调用本类构造方法this(参数)必须在第一行返回当前对象return this链式调用5. 构造方法创建对象时自动执行5.1 什么是构造方法构造方法是创建对象时自动调用的特殊方法classStudent{privateStringname;privateintage;// 无参构造publicStudent(){System.out.println(对象被创建了);}// 有参构造publicStudent(Stringname,intage){this.namename;this.ageage;}}5.2 构造方法的特点特点说明方法名必须和类名相同写错了就是普通方法没有返回值类型连void都不能写自动调用new的时候自动执行可以重载可以写多个构造方法5.3 注意事项// 写了有参构造最好手动写无参构造classStudent{publicStudent(Stringname){// 有参构造}// 如果不写无参构造new Student()会报错}原因如果写了有参构造系统就不会再提供默认的无参构造了。6. JavaBean一种规范JavaBean就是按照一定规范编写的类6.1 三条规范成员变量私有化用private提供无参构造方法方便框架反射创建对象提供getter和setter统一访问方式6.2 标准写法publicclassStudent{// 1. 私有成员变量privateStringname;privateintage;// 2. 无参构造publicStudent(){}// 3. 有参构造可选但建议写上publicStudent(Stringname,intage){this.namename;this.ageage;}// 4. getter/setterpublicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.ageage;}}6.3 IDEA快捷生成不用手写用快捷键MacCommand NWindowsAlt Insert选择Getter and Setter、Constructor即可自动生成。7. 内存图理解栈和堆7.1 Java的内存分区区域存储内容特点栈局部变量、方法调用方法执行完就释放堆对象、成员变量GC自动回收方法区类信息、静态变量类加载时存入7.2 基本数据类型 vs 引用数据类型inta10;// 基本类型值直接存在栈里StudentsnewStudent();// 引用类型栈里存地址对象在堆里图解栈 堆 ┌─────┐ ┌─────────────┐ │ a10│ │ Student对象 │ ├─────┤ │ namenull │ │ s │──────────────→│ age0 │ └─────┘ └─────────────┘7.3 三种情况的对象内存图情况1一个对象StudentsnewStudent();// 栈s存地址 → 堆Student对象情况2两个对象Students1newStudent();Students2newStudent();// 栈s1和s2存不同地址 → 堆两个独立对象情况3两个引用指向同一个对象Students1newStudent();Students2s1;// s2和s1指向同一个对象// 修改s1的属性s2也会变8. 成员变量 vs 局部变量维度成员变量局部变量定义位置类中、方法外方法内或参数作用域整个类方法内默认值有int0引用null没有必须初始化内存位置堆对象里栈生命周期随对象创建和销毁随方法调用和结束classStudent{privateintage;// 成员变量有默认值0publicvoidstudy(){inthour;// 局部变量没有默认值必须先赋值hour2;// 必须赋值才能用System.out.println(学了hour小时);}}9. 综合训练文字版格斗游戏9.1 需求创建两个角色互相攻击直到一方血量归零。9.2 代码实现publicclassCharacter{privateStringname;//属性privateintblood;publicCharacter(){}//构造方法publicCharacter(Stringname,intblood){this.namename;this.bloodblood;}publicvoidsetName(Stringname){//setget 函数this.namename;}publicStringgetName(){returnname;}publicintgetBlood(){returnblood;}publicvoidsetBlood(intblood){this.bloodblood;}publicvoidattack(Characterch1){//行为RandomrnewRandom();intattackr.nextInt(20)1;intbloodLivech1.getBlood()-attack;if(bloodLive0){bloodLive0;}ch1.setBlood(bloodLive);System.out.println(this.name打了ch1.nameattack点血量,ch1.name还剩bloodLive血量);}publicvoiddied(){System.out.println(this.getName()被打死了.);}}importjava.util.Scanner;publicclassdraft{publicstaticvoidmain(String[]args){ScannerscnewScanner(System.in);Characterch1newCharacter();Characterch2newCharacter();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()0ch2.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[]studentsnewStudent[3];// 给每个位置赋值students[0]newStudent(张三,18);students[1]newStudent(李四,19);students[2]newStudent(王五,20);// 遍历for(inti0;istudents.length;i){System.out.println(students[i].getName());}10.2 操作添加、删除、统计// 统计年龄大于18的学生intcount0;for(Students:students){if(s.getAge()18){count;}}// 删除指定位置把后面的往前移for(intiindex;isize-1;i){students[i]students[i1];}students[size-1]null;size--;11. 总结对比C vs Java维度C语言Java组织方式函数 结构体类数据方法打包数据保护无private getter/setter内存管理malloc/free手动new 自动GC构造初始化手动写init函数构造方法自动调用数组长度需自己维护arr.length

更多文章