Java面向对象编程与构造方法
一、面向对象思想 OOP1. 面向过程 VS 面向对象对比维度面向过程面向对象核心思想关注怎么做按步骤流程执行关注谁来做找对象分配职责代码组织以函数为单位数据和方法分离以对象为单位数据和行为封装在一起扩展性差修改一处影响全局好通过继承和多态轻松扩展适用场景简单小功能、性能敏感底层大型项目、复杂业务系统代表语言C语言Java、C、Python生活例子洗衣服面向过程手洗拿盆 → 接水 → 放衣服 → 加洗衣液 → 搓洗 → 漂洗 → 拧干 → 晾晒每一步都要自己动手中间想加浸泡步骤后面所有步骤都得调整。面向对象洗衣机洗拆分成对象人、衣服、洗衣机、洗涤剂 人 → 按开关只负责触发 洗衣机 → 自动完成进水→洗涤→排水→脱水→烘干内部复杂逻辑封装想升级功能换一台更好的洗衣机就行人的操作不变。2. 类和对象核心关系概念生活类比内存位置特点类Class建筑图纸方法区存储字节码抽象概念不占堆内存对象Object按照图纸盖出来的楼堆内存真实存在的实例拥有独立数据一句话总结一个类可以创建无数个对象对象之间互不干扰二、类的定义语法细节1. 类结构只有两块东西class 类名 { // 第一部分成员变量属性/特征 // 描述对象有什么 数据类型 变量名1; 数据类型 变量名2; // 第二部分成员方法行为/功能 // 描述对象能做什么 返回值类型 方法名1(参数列表) { // 方法体 } 返回值类型 方法名2(参数列表) { // 方法体 } } 细节补充类中不能直接写执行语句如System.out.println()所有执行逻辑必须放在方法里。2. 练习案例案例1Dog 狗类class Dog { // 属性 public String name; // 名字如旺财、小黑 public String color; // 毛发颜色如黄色、黑色 // 行为 public void bark() { System.out.println(name 汪汪汪); } public void wagTail() { System.out.println(name 开心地摇起了尾巴~); } // 新增狗自我介绍 public void introduce() { System.out.println(我是 color 色的狗狗我叫 name ); } }三、对象的实例化创建对象1. 实例化语法完整版// 标准创建格式 类名 对象名 new 类名(); // 访问成员 对象名.成员变量 值; // 给属性赋值 数据类型 变量 对象名.成员变量; // 获取属性值 对象名.成员方法(); // 调用方法 // 链式调用不推荐了解即可 new 类名().成员方法(); // 匿名对象用完即弃2. 两种赋值方式创建对象后给成员变量赋值主要有两种方式方式一直接赋值点号访问通过对象名.成员变量直接赋值适合创建对象后单独设置属性值// 创建对象 Student stu new Student(); // 直接赋值 stu.name 张三; stu.age 18; stu.className Java一班;特点简单直观适合少量属性赋值可以分步赋值灵活性高需要创建对象后才能赋值方式二构造方法赋值在创建对象时通过构造方法直接传入初始值适合创建时就确定属性值// 定义带参数的构造方法 class Student { public String name; public int age; public String className; // 有参构造方法 public Student(String name, int age, String className) { this.name name; this.age age; this.className className; } } // 创建对象时直接赋值 Student stu new Student(李四, 20, Java二班);特点创建对象和初始化一步完成代码简洁适合属性较多的情况可以保证对象创建时就具备完整状态3. 创建对象完整示例public class Test { public static void main(String[] args) { Dog dog1 new Dog(); dog1.name 旺财; dog1.color 黄色; dog1.bark(); // 输出旺财汪汪汪 Dog dog2 new Dog(); dog2.name 小黑; dog2.color 黑色; dog2.bark(); // 输出小黑汪汪汪 // ⚠️ 注意dog1 和 dog2 是堆内存中两块独立空间互不影响 dog1.introduce(); // 我是黄色的狗狗我叫旺财 dog2.introduce(); // 我是黑色的狗狗我叫小黑 } }4. 对象在内存中的存储内存区域存储内容示例说明栈内存main方法栈帧dog1引用变量 → 指向堆中的 Dog 对象旺财dog2引用变量 → 指向堆中的 Dog 对象小黑特点方法调用时分配方法结束自动释放引用变量本身存储在栈中保存的是堆中对象的地址多个引用可以指向同一个堆对象堆内存Dog 对象旺财name旺财color黄色Dog 对象小黑name小黑color黑色对象实际数据存储在堆中每个对象有独立的内存空间对象之间数据互不干扰由垃圾回收器GC管理回收四、对象初始化机制底层详解1. new 对象底层执行顺序执行代码Date d new Date(2021, 6, 9);步骤操作详细说明①类加载将 Date.class 字节码文件加载到方法区②分配堆内存在堆内存中为对象分配独立存储空间③解决竞争JVM 处理多线程同时 new 对象的内存分配竞争④默认初始化给所有成员变量赋系统默认值见下方对照表⑤就地初始化执行成员变量定义时直接赋值的代码⑥初始化对象头设置对象头信息哈希码、GC分代年龄、锁标记等⑦构造方法初始化执行构造方法中的代码进行自定义赋值2. 成员变量默认值对照表数据类型分类具体类型默认值整型byte / short / int0long0L浮点型float0.0fdouble0.0布尔型booleanfalse字符型char\u0000空字符不是空格引用类型String、数组、自定义类、接口null⚠️ 注意局部变量没有默认值使用前必须手动赋值3. 就地初始化代码示例class Date { // 就地初始化在声明时直接赋值 // 对象创建时这些值会在默认初始化之后被覆盖 public int year 1900; // 默认0 → 然后变成1900 public int month 1; // 默认0 → 然后变成1 public int day 1; // 默认0 → 然后变成1 } // 等价于下面的执行过程 // new Date() 时 // year 0默认→ year 1900就地 // month 0默认→ month 1就地 // day 0默认→ day 1就地五、成员变量 vs 局部变量对比维度成员变量属性局部变量定义位置类中、方法外方法内部 / 代码块内 / 方法形参所属主体属于对象实例变量或属于类静态变量属于方法方法调用时才存在内存位置堆内存实例变量或方法区静态变量栈内存方法入栈时分配默认值✅ 有默认值见上表❌ 没有默认值必须手动赋值生命周期对象创建时出生对象被GC回收时死亡方法调用时出生方法执行结束即死亡重名时可用 this.变量名 区分就近原则局部变量优先访问访问修饰符可以用 public / private / protected不能使用访问修饰符static修饰可以使用 static不能使用 static经典坑题1局部变量未初始化public class Test { int num; // 成员变量默认值为 0 public void show() { int localNum; // 局部变量未赋值 System.out.println(this.num); // ✅ 输出 0 System.out.println(localNum); // ❌ 编译报错变量 localNum 未初始化 } }经典坑题2变量重名覆盖public class Test { String name 成员变量; public void show(String name) { // 形参也是局部变量 System.out.println(name); // 输出传入的形参值局部优先 System.out.println(this.name); // 输出成员变量用this区分 } public static void main(String[] args) { Test t new Test(); t.show(局部变量); // 输出 // 局部变量 // 成员变量 } }六、构造方法1. 定义与作用构造方法是类中特殊方法new 创建对象时自动调用专门用于完成对象的初始化赋值。 关键理解构造方法不是创建对象而是初始化对象——对象的内存空间早在第②步就分配好了。2. 四大硬性特征特征说明错误示例方法名必须和类名完全一致大小写严格匹配public void Date()❌返回值没有返回值类型不能写 voidpublic void Date()❌调用时机new 时由 JVM 自动调用不能手动调用对象.构造方法()❌执行次数每个构造方法体执行一次通过this()可连锁触发多个构造方法重载支持方法重载参数列表不同参数相同只是顺序不同也算重载3. 构造方法分类 核心规则类型说明何时存在默认无参构造参数为空方法体为空类中没有任何构造方法时编译器自动生成自定义无参构造手动写的无参构造手动编写覆盖默认的自定义有参构造带参数的构造方法手动编写用于创建时直接赋值4. 构造方法代码示例带详细注释class Date { public int year; public int month; public int day; // 有参构造方法 public Date(int year, int month, int day) { // 用 this 区分成员变量和形参 this.year year; // 把形参 year 的值赋给成员变量 this.year this.month month; this.day day; System.out.println(有参构造方法执行); } // 手动补充无参构造 // 因为上面写了有参构造默认无参构造失效必须手动写 public Date() { this(2000, 1, 1); // 调用有参构造默认2000年1月1日 System.out.println(无参构造方法执行); } public void printDate() { System.out.println(year - month - day); } public static void main(String[] args) { Date d1 new Date(2025, 7, 1); // ✅ 调用有参构造 d1.printDate(); // 2025-7-1 Date d2 new Date(); // ✅ 调用无参构造手动补充的 d2.printDate(); // 2000-1-1 } }七、this 关键字1. this 核心定义this 代表当前调用方法的对象——谁调用当前方法this 就指向谁由编译器自动隐式传递。 理解关键this 本质上是一个隐藏参数每个非静态方法调用时编译器都会悄悄把当前对象的引用传进去。2. 为什么需要 this当方法形参名和成员变量名重名时遵循就近原则局部变量优先直接赋值无效// ❌ 错误写法成员变量根本没变 public void setDate(int year, int month, int day) { year year; // 等号左边是形参 year右边也是形参 year // 相当于形参给自己赋值成员变量 year 没变 month month; // 同上 day day; // 同上 }// ✅ 正确写法用 this 区分 public void setDate(int year, int month, int day) { this.year year; // this.year → 成员变量 year → 形参 this.month month; this.day day; }3. this 三种用法用法1this.成员变量最常用占比80%区分重名的成员变量和局部变量public void setAge(int age) { this.age age; // this.age 成员变量age 形参 } public String getName() { return this.name; // 这里的 this. 可省略但建议写上增加可读性 }用法2this.成员方法()本类中调用其他成员方法this 可省略建议省略public void methodA() { System.out.println(方法A执行); } public void methodB() { this.methodA(); // 完整写法 methodA(); // ✅ 省略写法推荐 }用法3this() 调用本类其他构造方法严格规则三条铁律规则说明位置限制必须写在构造方法的第一行代码唯一性一个构造方法中只能调用一次 this()禁止循环不能形成循环调用A→B→A 会编译报错class Student { public String name; public int age; public String classId; // 全参构造 public Student(String name, int age, String classId) { this.name name; this.age age; this.classId classId; System.out.println(全参构造执行); } // 两参构造 → 调用全参构造 public Student(String name, int age) { this(name, age, 未分配班级); // 调用全参构造设置默认班级 System.out.println(两参构造执行); } // 单参构造 → 调用两参构造 public Student(String name) { this(name, 18); // 调用两参构造设置默认年龄 System.out.println(单参构造执行); } public static void main(String[] args) { Student s1 new Student(张三, 20, Java一班); Student s2 new Student(李四, 19); Student s3 new Student(王五); } }4. this 禁忌静态方法static中不能使用 this因为静态方法属于类不属于对象而 this 代表当前对象。public static void main(String[] args) { // this.name hello; // ❌ 编译报错 // this.show(); // ❌ 编译报错 } public static void staticMethod() { // this.age 10; // ❌ 编译报错 }八、构造方法 this 连锁调用public class Car { String brand; int speed; public Car() { this(宝马, 0); // ① 调用全参构造 System.out.println(无参构造); } public Car(String brand, int speed) { this.brand brand; this.speed speed; System.out.println(全参构造); } public Car(String brand) { this(); // ② 调用无参构造触发连锁 this.brand brand; // ③ 覆盖 brand 为特斯拉 } public static void main(String[] args) { Car c new Car(特斯拉); System.out.println(c.brand 时速 c.speed); } }执行顺序和输出1. new Car(特斯拉) → 进入 Car(String brand) 2. this() → 进入 Car() 无参构造 3. this(宝马, 0) → 进入 Car(String brand, int speed) 4. 输出全参构造 ← 第1次打印 5. 回到无参构造输出无参构造 ← 第2次打印 6. 回到一个参数构造执行 this.brand brand覆盖为特斯拉 7. 最终输出特斯拉 时速0⚠️ 注意这里一个对象创建过程中执行了 3个构造方法体但对象只创建了一次。九、本章综合完整案例public class Student { // 成员变量 public String name; public int age; public String className; // 班级 // 构造方法 // 1. 无参构造 → this调用全参构造 public Student() { this(未命名, 18, 未分班); System.out.println(【构造】无参构造执行); } // 2. 两参构造 → this调用全参构造 public Student(String name, int age) { this(name, age, 默认班级); System.out.println(【构造】两参构造执行); } // 3. 全参构造实际初始化方法 public Student(String name, int age, String className) { System.out.println(【构造】全参构造执行真正干活); this.name name; this.age age; this.className className; } // 成员方法 public void setStudent(String name, int age) { this.name name; this.age age; System.out.println(修改学生信息完成); } public void print() { System.out.println(姓名 this.name 年龄 this.age 班级 this.className); } public void study() { System.out.println(this.name 正在认真学习Java); } // 测试入口 public static void main(String[] args) { System.out.println( 测试1无参构造 ); Student s1 new Student(); s1.print(); System.out.println(\n 测试2两参构造 ); Student s2 new Student(张三, 18); s2.print(); System.out.println(\n 测试3全参构造 ); Student s3 new Student(李四, 20, Java2026班); s3.print(); System.out.println(\n 测试4修改信息 ); s3.setStudent(王五, 21); s3.print(); s3.study(); } }运行结果 测试1无参构造 【构造】全参构造执行真正干活 【构造】无参构造执行 姓名未命名年龄18班级未分班 测试2两参构造 【构造】全参构造执行真正干活 【构造】两参构造执行 姓名张三年龄18班级默认班级 测试3全参构造 【构造】全参构造执行真正干活 姓名李四年龄20班级Java2026班 测试4修改信息 修改学生信息完成 姓名王五年龄21班级Java2026班 王五正在认真学习Java十、核心考点总结序号考点关键词1类是抽象模板对象是具体实例类图纸→ 对象楼2类的核心组成成员变量属性 成员方法行为3对象初始化三步默认初始化 → 就地初始化 → 构造方法初始化4构造方法特征名同类、无返回值、new自动调5⚠️ 有参构造后无参失效手写有参 → 默认无参消失 → 需手动补6this 三大作用区分重名 / 调本类方法 / 构造互调7this() 规则构造方法中、第一行、不循环8成员 vs 局部成员有默认值堆局部无默认栈9⚠️ static 禁 this静态方法属于类不属于对象