![Day12 --【Java全栈】面向对象编程[1]](http://pic.xiahunao.cn/yaotu/Day12 --【Java全栈】面向对象编程[1])
目录全景定位先搞懂它到底是啥思路第一种面向过程编程POP第二种面向对象编程OOP1. 核心基础类与对象通俗理解2. 类的两大组成3. 最简代码示例先看看大概长什么样4. 如何创建对象呢5. 完整执行顺序(从上到下一步步来)第一步分配内存空间第二步默认初始化第三步调用构造方法执行初始化第四步返回对象的引用地址6. 进阶Java 创建对象的 5 种常见方式7. 常见误区汇总8. 对象在内存里的样子呼应之前的值传递全景定位先搞懂它到底是啥思路编程的本质是把现实里的事情翻译成代码让电脑执行。翻译的思路有两种主流方向第一种面向过程编程POP核心思路是「怎么做」把事情拆成一步步的步骤按顺序写代码执行。 通俗理解做一杯奶茶面向过程的写法就是拿空杯子倒入茶底加入牛奶放糖搅拌封口出餐全程是你盯着每一步从头到尾指挥流程。第二种面向对象编程OOP核心思路是**「让谁来做」**先把事情里的角色、事物拆出来每个角色有自己的特征和本事然后让这些角色互相配合完成任务。 通俗理解同样做奶茶面向对象的写法是先定义三个角色奶茶杯有容量、温度这些特征能装液体奶茶师有姓名、工号这些特征会做奶茶、会封口订单有口味、价格这些特征能生成取餐号你不用管奶茶师具体怎么做只要跟他说「做一杯珍珠奶茶」他自己会按流程做完把成品给你。 记忆正式定义面向对象是一种编程设计思想它把现实世界的事物抽象成程序里的「类」每个类包含「属性特征」和「方法行为」使用时创建出类的具体「对象」通过对象之间的交互完成业务逻辑。Java 就是最典型的面向对象编程语言所有代码都必须写在类里面。1. 核心基础类与对象面向对象的世界里最基础的两个概念就是「类」和「对象」所有特性都是围绕它们展开的。通俗理解类Class对具有相同属性和相同行为的一组对象的抽象描述是创建对象的模板。类 设计图纸/模板比如奶茶店的统一配方卡规定了奶茶该有哪些配料、怎么做。它是抽象的不能直接喝。对象Object也叫实例是类的具体个体具备类定义的所有属性和方法。对象 按模板做出来的具体产品比如按配方做出来的第一杯珍珠奶茶、第二杯芋泥奶茶。它们是真实存在的个体每一杯都有自己的温度、甜度。简单说类是模板对象是模板做出来的具体实例。一个类可以做出无数个对象。2. 类的两大组成注这两个概念之前已经详细讲过这里快速回顾不太熟悉的可以翻看之前的笔记。属性也叫成员变量描述对象的特征比如奶茶的甜度、温度方法也叫成员方法描述对象的行为比如奶茶能加配料、奶茶师能做奶茶3. 最简代码示例先看看大概长什么样// 1. 定义一个类奶茶类模板 public class MilkTea { // 属性描述特征 String taste; // 口味 int temperature; // 温度 double price; // 价格 // 方法描述行为 public void drink() { System.out.println(喝一杯 taste 奶茶温度 temperature 度); } } // 2. 创建对象、使用对象 public class Test { public static void main(String[] args) { // 用new关键字根据类创建一个具体的对象 MilkTea pearlTea new MilkTea(); // 给对象的属性赋值 pearlTea.taste 珍珠; pearlTea.temperature 60; pearlTea.price 12; // 调用对象的方法 pearlTea.drink(); // 输出喝一杯珍珠奶茶温度60度 } }4. 如何创建对象呢 通俗理解你有一张奶茶配方图纸类但图纸不能直接喝。创建对象就像按照图纸真实做出一杯能喝的奶茶先拿一个空杯子在内存里开辟空间按配方默认装好基础配料给属性赋默认值按你的要求调整甜度、温度调用构造方法初始化属性给你一个取餐号凭号取餐返回对象的引用地址你手里的取餐号不是奶茶本身是找到奶茶的凭证这个「取餐号」就是对象引用杯子里的奶茶才是真正的对象本体。 记忆创建对象的核心语法Java 中创建对象最核心、最常用的方式就是用new关键字语法格式类名 对象名 new 类名(参数); // 构造方法名和类名完全相同举个完整的例子// 先有一个奶茶类模板 public class MilkTea { // 属性 private String taste; private double price; // 无参构造方法 public MilkTea() { } // 有参构造方法 public MilkTea(String taste, double price) { this.taste taste; this.price price; } } // 创建对象 public class Test { public static void main(String[] args) { // 方式1用无参构造创建对象之后再手动赋值 MilkTea tea1 new MilkTea(); // 方式2用有参构造创建对象创建同时就初始化属性 MilkTea tea2 new MilkTea(珍珠, 12); } }术语对应创建对象的过程也叫实例化做出来的具体对象也叫实例。 核心执行 new 的时候底层到底做了4件事很多人以为「构造方法创建了对象」这是新手最高频的误区。✅ 正确结论new关键字负责分配堆内存、生成空白对象雏形构造方法负责给空白对象初始化属性装配成真正可用的完整对象。二者分工不同、有明确先后顺序共同完成一个可用对象的创建。5. 完整执行顺序(从上到下一步步来)第一步分配内存空间JVM 在堆内存里开辟一块独立的空间用来存放这个对象的所有属性。此时空白对象雏形已经有了内存位置。第二步默认初始化给对象的所有属性赋上「零值」保证不会报错基本数字类型int、double等默认是 0 / 0.0boolean 类型默认是 falsechar 类型默认是 \u0000空字符比较特殊了解即可引用类型String、其他对象默认是 null空什么都没有第三步调用构造方法执行初始化执行你写的构造方法里的代码给属性赋上你指定的值。调用无参构造属性保持默认值你可以之后自己 set调用有参构造创建完立刻就把属性设置好第四步返回对象的引用地址把堆内存里这个对象的内存地址返回给栈里的变量名比如tea1。 你手里拿到的变量存的不是对象本身只是对象的地址也叫「对象引用」。关键概念引用变量 ≠ 对象本体这是理解 Java 引用类型、值传递、空指针的核心一定要分清概念存在位置存的是什么通俗类比对象引用变量名比如 tea1栈内存对象的内存地址一串数字取餐号对象本体堆内存真实的属性数据奶茶本身注堆栈的详细定义明天会单独补充暂且可以理解为栈是临时操作台堆是大仓库。最经典的例子多个引用指向同一个对象public class Test { public static void main(String[] args) { // 创建一杯珍珠奶茶tea1 拿着它的地址 MilkTea tea1 new MilkTea(珍珠, 12); // 把 tea1 的地址赋值给 tea2 MilkTea tea2 tea1; // 用 tea2 修改价格 tea2.setPrice(15); // 用 tea1 读取价格发现也变了 System.out.println(tea1.getPrice()); // 输出 15 } } 原理tea2 tea1只是复制了「取餐号」并没有新做一杯奶茶。两个引用指向堆里同一个对象不管用哪个引用去改改的都是同一个东西。 这就是之前讲「引用类型值传递」的底层本质传的是地址的副本两个地址指向同一个对象。6.进阶Java 创建对象的 5 种常见方式日常开发 99% 的场景都用第一种new剩下的了解即可混个眼熟new 关键字创建最常用调用构造方法灵活可控反射创建用Class.forName().newInstance()动态创建对象框架底层常用克隆clone基于已有对象复制一个新对象对应之前讲的深拷贝/浅拷贝反序列化创建把文件/网络里的字节数据还原成Java对象第三方工具创建比如 Spring 容器帮你创建 Bean本质也是反射你不用手动 new7. 常见误区汇总❌误区一构造方法负责创建对象✅ 正解new负责分配内存、生成空白对象雏形构造方法负责初始化属性二者共同完成一个可用对象的创建。哪怕构造方法报错了对象的内存在报错之前已经在堆里分配好了——这证明了分配内存是new干的活不是构造方法干的。不过如果构造方法抛了异常这块内存最终会被 JVM 回收对象不会真正可用。❌误区二写了有参构造还能直接 new 无参✅ 正解只要你手动写了任意一个构造方法编译器就不会自动生成默认无参构造了。想继续用new MilkTea()必须手动把无参构造写出来。❌误区三对象赋值就是复制了一个新对象✅ 正解tea2 tea1只是复制了地址两个引用指向同一个对象改一个另一个会跟着变。想复制新对象要用之前讲的深拷贝。❌误区四对象在栈内存里✅ 正解对象本体永远在堆内存里栈内存里只存对象的引用地址以及基本类型的局部变量。❌误区五一个类只能创建一个对象✅ 正解一个类可以创建无数个对象每个对象在堆里都有独立的内存空间属性互不干扰。空指针异常NullPointerException的本质引用变量的值是 null没有指向任何对象你还去调用它的方法、访问它的属性就会报空指针。MilkTea tea null; System.out.println(tea.getPrice()); // 直接报空指针异常 通俗理解相当于拿着一张空白的、没有编号的取餐号去仓库取奶茶肯定找不到对应商品系统就会报错。8. 对象在内存里的样子呼应之前的值传递 进阶理解和之前学的「值传递」完全对应创建对象时对象本体存在堆内存里保存所有属性的真实数据变量名比如上面的pearlTea存在栈内存里存的是堆里对象的内存地址也叫「对象引用」。你把对象传给方法时传的是地址的副本这就是之前讲的「引用类型值传递」的底层原因。❌ 当场避坑类名必须大驼峰首字母大写和方法名的小驼峰区分开这是Java强制规范。一个Java文件里可以有多个类但只能有一个public类且文件名必须和public类名完全一致。 和之前知识点的串联和构造方法关联构造方法是对象创建时的初始化入口创建对象时一定会调用对应的构造方法。ps:堆栈明天结合创建对象说一说最近被压力了难受