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

Java学习--面向对象基础

文章摘要

面向对象是Java编程的核心思想之一。它不只是“创建一个类、new一个对象”这么简单,更重要的是学会把数据和操作数据的行为组织在同一个对象中,并通过构造器完成初始化,借助this明确当前对象,再利用封装性控制外部对数据的访问。

简单理解:类是对象的模板,对象是类的实例;属性保存对象的数据,方法描述对象能够执行的行为。

1.面向对象的基本概念

1.1面向对象到底是什么

面向对象强调:现实世界中的事物可以抽象为对象,对象既携带数据,也可以执行与这些数据相关的操作。程序不再只是零散变量和函数的堆积,而是围绕一个个对象组织起来。

例如,要保存学生“张三”的姓名和年龄,仅用一个基本数据类型无法同时描述String类型的姓名和int类型的年龄。此时可以定义Student类,把name和age组合成一个新的数据类型。

核型价值:确定了对象,就能找到与该对象相关的数据和行为,代码的结构会更清晰,也更接近人类理解现实事务的方法。

2.类、对象、属性和方法

2.1类是模板

类可以理解为一张模板或一份设计图,他规定对象应该具备哪些属性和方法。在项目中,通常会把用于描述数据的类放在entity包中,这类类常被成为实体类

package entity; public class Student { public String name; // 属性:姓名 public int age; // 属性:年龄 public void run() { // 方法:行为 System.out.println("跑步"); } }

2.2 对象是类的实例

对象是根据类创建出来的具体实例。类本身只定义结构,真正携带数据的是对象。创建对象使用new关键字。

Student s1 = new Student(); s1.name = "张三"; s1.age = 18; s1.run();

上面s1是一个引用变量,它保存Student对象在内存中的地址。通过“对象名.属性名”可以读写属性,通过“对象名。方法名()”可以调用行为。

3.对象在内存中的执行过程

理解对象的内存过程,可以帮助我们解释为什么对象之间可能互不影响,也可以解释为什么多个变量指向同一个对象时会相互影响。

1. Java 源文件被编译为 .class 字节码,并在运行时加载。

2. main 方法进入方法调用栈。

3. 执行 new Student() 时,在堆内存中开辟一块空间。

4. 对象的成员变量先获得默认值,例如 name 为 null、age 为 0。

5. 堆内存地址返回给引用变量 s1。

6. 给 s1.name 和 s1.age 赋值,本质上是在修改堆中对象的数据。

7. 调用 s1.run() 时,根据对象类型找到 Student 类中的 run 方法并执行。

容易混淆的点:s1不是对象本身,它是保存对象地址的引用变量;真正的Student对象位于堆内存中。

4.类和对象的常见注意事项

  • 类名一般采用大驼峰命名法,例如 Student、Teacher、SchoolInfo。
  • 定义在类中、方法外的变量叫成员变量;定义在方法或代码块中的变量叫局部变量。
  • 成员变量在创建对象时会自动获得默认值,局部变量则必须先赋值后使用。
  • 一个 .java 文件可以定义多个类,但只能有一个 public 类,并且 public 类名必须与文件名一致。
  • 不同 new 出来的对象通常互不影响;多个引用变量指向同一个对象时,修改对象会被所有引用看到。
数据类型成员变量默认值
byte、short、char、int、long0
float、double0.0
booleanfalse
String、数组、其他引用类型null

5.this关键字

this表示当前对象。成员方法运行时,一定是由某个对象发起调用的,this就指向这个正在调用方法的对象。

5.1 为什么需要this

当方法名或局部变量名与成员变量名相同时,Java会优先使用离自己更近的局部变量或参数。此时使用this.成员变量可以明确访问的是当前对象的属性。

public class Student { private String name; private int age; public void setName(String name) { this.name = name; } }

阅读方式this.name = name 可以读成:把参数 name 的值,赋给当前对象的成员变量 name。

5.2 this还能调用成员变量

public void run(String name) { System.out.println(this.name); System.out.println("没事跑跑步"); } public void eat() { this.run("Jerry"); }

在没有歧义时,this. 可以省略;但在实体类中显式写出 this,往往能让代码含义更清楚。

6.构造器:创建对象时完成初始化

构造器是创建对象时自动执行的特殊结构。它看起来像方法,但没有返回值类型,名称必须与类名完全一致。

public Student() { // 无参构造器 }

6.1 无参构造器

如果类中没有显示编写任何构造器,Java会提供一个默认的无参构造器。因此Student s = new Student();可以正常执行。

6.2 有参构造器

有参构造器可以在创建对象的同时完成属性赋值。包含所有成员变量参数的构造器,通常称为全参构造器。

public Student(String name, int age) { this.name = name; this.age = age; } // 创建对象 Student s1 = new Student("张三", 18);

重要规则:只要类中显式编写了有参构造器,Java 就不会再自动提供默认无参构造器。仍需无参创建对象时,必须手动补写无参构造器。

注意:在 IntelliJ IDEA 中,可以通过 Alt + Insert 或 Generate 菜单快速生成无参、部分参数或全参构造器。

7.封装:控制对向数据的访问

封装是Java面向对象的三大特性之一,另外两个是继承和多态。封装的核心不是简单地“把属性改成private”,而是隐藏不应该被外部直接操作的实现细节,并通过公开方法提供受控访问。

7.1 为什么不能把所有属性都设为public

如果属性使用 public 修饰,项目中的其他类可以随意修改它。比如学校名称原本固定为“北京大学”,但外部代码却可以把它改成其他内容,这会破坏对象数据的合理性。

7.2 标准封装步骤

1. 使用 private 修饰成员变量,让属性只能在当前类内部直接访问。

2. 根据需要提供 public 的 Getter 方法读取属性。

3. 根据需要提供 public 的 Setter 方法修改属性。

4. 在 Setter 中加入参数校验,可以阻止非法数据进入对象。

public class School { private String schoolName = "北京大学"; private String address; private String phone; public String getSchoolName() { return this.schoolName; } public String getAddress() { return this.address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return this.phone; } public void setPhone(String phone) { this.phone = phone; } }

上面的 schoolName 只提供 get 方法,因此外部只能读取,不能修改;address 和 phone 同时提供 get、set 方法,因此既可以获取也可以更新。

8.实体JavaBean

实体JavaBean可以理解为用于携带数据的实体类。对象负责保存和传递数据,而对象又必须依赖实体类来创建,因此实体类是Java程序中非常基础的组成部分。

8.1 初学者阶段常见的JavaBean写法

  • 类通常放在 entity、model 或 domain 包中。
  • 成员变量使用 private 修饰。
  • 提供无参构造器。
  • 根据需要提供全参构造器。
  • 为属性提供 Getter 和 Setter。
  • 类名能够清楚表达其所描述的数据,例如 Student、Product、Order。
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } }

9.成员变量与局部变量的区别

比较项成员变量局部变量
定义位置类中、方法外方法、构造器或代码块内部
默认值创建对象时自动获取默认值没有默认值,使用前必须赋值
内存位置通常随对象存放在堆中通常随方法调用存在与栈帧中
作用域

可以被类中的成员方法访问

只能在所属的代码块中使用

生命周期

通常与对象共存亡

随方法调用产生,方法结束后消失

访问方式

常通过 this.变量名访问

直接使用变量名

记忆口诀成员变量属于对象,局部变量属于一次方法执行。

10.综合示例:把知识点串起来

下面的示例同时使用了类、对象、成员变量、this、构造器和封装。它也是初学阶段最值得反复手写的一段代码。

public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.setAge(age); } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { if (age >= 0 && age <= 150) { this.age = age; } } public void introduce() { System.out.println("我叫" + this.name + ",今年" + this.age + "岁。"); } }
public class StudentTest { public static void main(String[] args) { Student s1 = new Student("张三", 18); s1.introduce(); Student s2 = new Student(); s2.setName("李四"); s2.setAge(20); s2.introduce(); } }

这个版本比直接公开属性更安全:年龄只能通过 setAge 修改,而且能够在方法中检查范围。这正是封装的实际意义——让对象自己维护数据的有效性。

11.初学者常见错误

错误原因和修正
构造器写了void

构造器没有返回值类型,连 void 也不能写

有参构造器存在,却继续 new Student()

显式写有参构造器后,默认无参构造器失效,需要手动补写

this.name = this.name

左右两边都指成员变量,没有使用参数值;应写 this.name = name

局部变量未赋值就使用

局部变量没有默认值,必须先初始化

所有属性都设为 public

外部可以绕过校验随意修改,应使用 private 配合 Getter / Setter。

把类和对象混为一谈

类是模板,对象是根据模板创建的具体实例

以为两个引用就是两个对象

两个变量可能保存同一个地址,修改其中一个会影响另一个

12.总结

学习 Java 面向对象时,可以按照“类定义结构 → new 创建对象 → 构造器初始化 → this 指向当前对象 → private 隐藏属性 → Getter / Setter 控制访问”的顺序理解。掌握这一条主线后,后续学习继承、多态、接口、集合以及 Spring 项目中的实体类都会轻松很多。

最终知识链类是模板,new 产生对象;对象在堆中保存数据;this 表示当前对象;构造器负责初始化;封装负责保护数据;JavaBean 负责携带和传递数据。

13.思考问题

1.为什么成员变量有默认值,而局部变量没有?

2.只写有参构造器后,为什么无参构造器会失效?

http://www.jsqmd.com/news/1140061/

相关文章:

  • 匿名类·学习笔记
  • SITS 2026:基于语义理解与行为建模的下一代AI自动化测试框架
  • Lumafly完整指南:3分钟学会空洞骑士模组管理新方法
  • 如何轻松找回丢失的QQ空间记忆:GetQzonehistory实用数据恢复指南
  • 薄膜分选的困境与突围:高光谱助力从混合垃圾到纯净再生资源
  • 大模型Prompt模板管理:从硬编码到配置中心的工程化演进
  • CNC加工厂成本核算为什么总算不清?材料、工时、外协和返工怎么管
  • 我在CSDN踩过的10个技术坑:真实运维/开发/AI实战避坑指南
  • 电磁寻迹智能车PCB设计:从5路电感布局到0603/0805封装选择的3个避坑点
  • 新手小号选购指南!3种学习场景对号入座,高口碑型号推荐
  • Excel-to-JSON本地化Excel插件发布 - 在Excel中安全离线转换数据
  • 5款录音转文字工具测评:专业场景转写效率对比
  • PCIe 第30针脚绝缘操作详解:解决N卡HW Power Brake Slowdown的5个关键步骤与风险提示
  • PCB拼版 V-CUT与邮票孔实战对比:3大场景选型与5项设计避坑指南
  • [具身智能-567]:DOFBOT、ROSMASTER 、Rider、MUTO、DOGZILLA
  • 外网也能隔空打印!这款神器,让打印机突破局域网限制!
  • 3分钟快速上手:用RoundedTB让Windows任务栏焕然一新的终极指南
  • 终极指南:用XUnity.AutoTranslator轻松实现Unity游戏本地化
  • 在几何最起码常识面前2300数学定理、公理不堪一击
  • 【物业管理数字化升级:收费、巡检、台账痛点一站式解决方案】
  • 二类耗材 UDI 落地实操心得,喷码赋码 + 手持 PDA 一体化管控经验
  • 计算机毕业设计之基于YOLOv8的中草药识别检测
  • YOLOv8精度调优:锚框聚类与数据增强实战
  • 如何快速部署手机号码定位系统:企业级解决方案完全指南
  • 如何快速获取QQ空间历史说说:GetQzonehistory完整指南与实战教程
  • SSL证书更新全攻略:从原理到实践,手把手教你网站安全配置
  • Claude Code离线安装方案揭秘
  • 眼底相机杂散光抑制实战:柯勒照明与黑点板应用,鬼像能量降低至0.1%以下
  • 别让你的变量“迷路”:Python进程间通信的3种正确姿势
  • K老答——非本体论