17. 【Java】类(抽象)与对象:万物皆对象
摘要本文是 Java 面向对象编程的入门指南旨在帮助初学者理解类与对象的核心概念。文章通过生动的比喻如“图纸”与“实物”阐释了类作为蓝图、对象作为实例的关系详细讲解了如何定义类、创建对象、使用构造方法以及理解内存模型并通过实战案例展示了如何用面向对象思维重构程序。关键词Java, 面向对象编程, 类, 对象, 构造方法我们已经完成了前两个阶段的学习。掌握了变量、运算符、循环、方法、数组、字符串……现在已经能写出像“命令行计算器”这样实用的程序了。但我们之前写代码的方式更像是“按流程办事”先做 A再做 B再做 C。这种思维叫面向过程。它适合解决一些相对简单的问题比如计算器、排序、数据处理。可现实世界是复杂的。你不是在“处理流程”你是在和“人”、“物”、“事”打交道。一个电商系统里有用户、商品、订单一个学校系统里有学生、老师、课程——这些“东西”都有自己的属性叫什么、多大了和行为能做什么。如果只用面向过程的方式去建模你会发现代码越来越乱数据和方法散落在各处修改一个地方可能会影响几十个地方。我们需要一种更接近人类认知世界的方式来组织代码。这就是面向对象编程Object-Oriented Programming简称 OOP。今天我们来迈出面向对象的第一步理解类Class和对象Object。1. 从“流程”到“世界” —— 思维方式的转变在面向过程的世界里程序像是一份菜谱第一步切菜第二步热油第三步下锅翻炒……步骤清晰但所有食材都是“被操作”的它们本身没有“灵魂”。在面向对象的世界里程序更像是一个舞台剧舞台上有很多“角色”对象每个角色都有自己的属性名字、年龄、外貌和行为走路、说话、唱歌。导演你的程序通过给角色发送指令调用方法让整个舞台运转起来。这种思维方式的转变是学习 Java 最关键的一步。它不只是一个技术问题更是一个世界观问题。你可以这样想面向过程是“我要怎么做”面向对象是“谁来做这件事”。前者强调步骤后者强调责任。2. 类和对象 —— 一个是“图纸”一个是“实物”在 Java 里有两个紧密相连但完全不同的概念类Class是模板、是蓝图、是设计图。它定义了某类事物应该有什么属性数据和行为方法但它本身不是具体的东西。对象Object是根据类创建出来的具体实例。它是实实在在存在于内存中的东西有自己的状态。打个比方类 一张“汽车设计图纸”。它上面画了汽车应该有四个轮子、一个方向盘、一个发动机也画了汽车可以“启动”、“加速”、“刹车”。但图纸本身不是汽车你不能开着它上路。对象 根据这张图纸造出来的一辆真车。它有具体的颜色、具体的车牌号、具体的里程数。你可以坐进去发动它开走它。同一个类可以创建出无数个对象。比如从同一张“学生设计图”可以造出张三、李四、王五——他们都有姓名、年龄、学号但具体值各不相同。3. 定义一个类 —— 画出你的“设计图”在 Java 中定义类的语法我们其实已经见过无数次了publicclassStudent{// 属性成员变量Stringname;intage;StringstudentId;// 行为成员方法publicvoidstudy(){System.out.println(name 正在学习...);}publicvoidsayHello(){System.out.println(你好我是 name今年 age 岁。);}}这是一个最简单的类定义。它描述了“学生”这个概念学生有属性name姓名、age年龄、studentId学号学生有行为study()学习、sayHello()打招呼我们还没有加private、public这些修饰符——那是“封装”的内容我们下一篇再讲。现在先让所有属性都是默认的包可见一切从简。注意一个 Java 文件可以定义多个类但public修饰的类必须和文件名一致。我们通常一个文件只写一个类。4. 创建对象 —— 把“图纸”变成“实物”有了类这个“设计图”我们就可以用它来创建具体的对象了。创建对象使用new关键字publicclassMain{publicstaticvoidmain(String[]args){// 根据 Student 类创建一个具体的学生对象Students1newStudent();// 给对象的属性赋值s1.name张三;s1.age20;s1.studentId2024001;// 调用对象的行为s1.sayHello();// 输出你好我是 张三今年 20 岁。s1.study();// 输出张三 正在学习...// 创建另一个学生对象Students2newStudent();s2.name李四;s2.age22;s2.studentId2024002;s2.sayHello();// 输出你好我是 李四今年 22 岁。}}看到了吗s1和s2是两个完全独立的对象。它们都来自同一个Student类但各自有各自的name、age、studentId。修改s1的name不会影响s2。5. 构造方法 —— 对象创建的“生产线”刚才我们创建对象的方式是两步走Students1newStudent();// 1. 先创建空对象s1.name张三;// 2. 再手动赋值这样有点麻烦。更好的方式是在创建对象的同时就把属性设置好。这就要用到构造方法Constructor。构造方法是一种特殊的方法它的名字必须和类名完全一样并且没有返回值类型连void都不写。它会在new的时候自动被调用用来初始化对象。publicclassStudent{Stringname;intage;StringstudentId;// 无参构造方法publicStudent(){// 可以什么都不做或者给默认值}// 有参构造方法创建对象的同时传入姓名、年龄、学号publicStudent(Stringname,intage,StringstudentId){this.namename;// this.name 是成员变量name 是参数this.ageage;this.studentIdstudentId;}publicvoidsayHello(){System.out.println(你好我是 name今年 age 岁。);}}然后创建对象就变得很简洁了Students1newStudent(张三,20,2024001);s1.sayHello();// 直接就有值了不需要再一行行赋值关于this在构造方法以及后面的 setter 方法中我们经常看到this.name name;这种写法。this是一个关键字它表示“当前对象本身”。当成员变量和局部变量比如构造方法的参数重名时this.name明确表示“这个对象的name字段”而name表示参数。如果你不写this编译器会优先使用局部变量参数导致成员变量没有被赋值这是一个很隐蔽的 bug。// 错误写法没有 thispublicStudent(Stringname,intage,StringstudentId){namename;// 两边都是参数成员变量没被赋值}所以this在构造方法和 setter 中几乎是必须的。养成习惯只要成员变量和参数同名就用this区分。构造方法的注意事项如果你没有定义任何构造方法Java 会默认给你一个无参构造方法。但如果你定义了任何一个有参构造方法Java不会再给你默认的无参构造方法。如果你还需要无参的必须手动写出来。构造方法可以重载多个构造方法参数不同就像普通方法一样。6. 类与对象的内存模型 —— “图纸”和“实物”在哪儿我们粗略了解一下内存分配这对理解“引用类型”很有帮助。当你写Student s1 new Student(张三, 20, 2024001);时内存里发生了两件事在堆内存Heap中创建了一个Student对象里面存储了name张三、age20、studentId2024001这些数据。在栈内存Stack中创建了一个局部变量s1它里面存储的不是对象本身而是对象的地址一个指向堆内存中那个对象的引用。所以s1就像是一个“遥控器”它指向真正的对象。当你用s1.sayHello()时Java 会通过这个遥控器找到堆中的对象然后执行它的方法。这也解释了为什么Students1newStudent(张三,20,2024001);Students2s1;// s2 指向同一个对象s2.name李四;System.out.println(s1.name);// 输出 李四因为s1和s2指向的是同一个对象通过s2修改了对象的属性s1看到的内容自然也跟着变了。7. 实战用面向对象的方式重构“个人名片生成器”还记得我们在第 6 篇写的“个人名片生成器”吗那时候我们用数组来传递信息不够优雅。现在学了面向对象我们可以用类来封装这些信息了。// 文件Person.javapublicclassPerson{Stringname;intage;Stringcity;Stringmotto;// 无参构造publicPerson(){}// 全参构造publicPerson(Stringname,intage,Stringcity,Stringmotto){this.namename;this.ageage;this.citycity;this.mottomotto;}// 行为打印名片publicvoidprintCard(){System.out.println(\n 你的专属名片 );System.out.println(姓名name);System.out.println(年龄age岁);System.out.println(城市city);System.out.println(座右铭\motto\);System.out.println(------------------------);System.out.println(愿你如座右铭所言活出精彩);}}// 文件Main.javaimportjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){ScannerscannernewScanner(System.in);System.out.println( 欢迎来到「个人名片生成器」 );System.out.print(请输入你的姓名);Stringnamescanner.nextLine();System.out.print(请输入你的年龄);intageInteger.parseInt(scanner.nextLine());System.out.print(请输入你所在的城市);Stringcityscanner.nextLine();System.out.print(请输入你的座右铭);Stringmottoscanner.nextLine();// 用类来封装数据而不是数组PersonpersonnewPerson(name,age,city,motto);person.printCard();scanner.close();}}看到了吗代码变得更清晰、更可读了。Person类把数据和操作数据的方法放在了一起这就是面向对象的封装思想。我们下一篇会深入讲它。8. 面向对象的核心思想今天的内容其实已经触及了面向对象编程的三个核心特性之一——封装把数据和操作数据的方法放在一起。另外两个是继承和多态我们会在后面的文章中慢慢展开。面向对象的四个核心概念抽象Abstraction从具体事物中提取出共同的、本质的特征形成类的过程。比如从张三、李四、王五中抽象出“学生”这个概念。封装Encapsulation把数据和操作数据的方法绑定在一起并对外隐藏内部细节。比如你把手机的内部电路封装起来用户只需要按键调用方法不需要知道电路怎么工作的。继承Inheritance一个类可以基于另一个类来定义复用父类的属性和方法。多态Polymorphism同一个行为比如“叫”不同对象可以有不同的实现方式猫叫、狗叫、狮子叫。这些概念我们接下来会逐一展开。9. 给初学者的几个小建议不要试图一下就理解所有面向对象的概念。今天先理解“类就是图纸对象就是实物”把这个比喻刻在脑子里。多定义自己的类。看到任何一个现实中的事物书、汽车、员工、课程试着用类去描述它有哪些属性、哪些行为。学会区分“谁做”和“怎么做”面向对象的核心是把责任分配到对象上而不是集中在主方法里。今天的总结今天我们跨过了面向对象的第一道门槛类是模板、是蓝图定义了一类事物的属性和行为。对象是根据类创建的具体实例有自己独立的状态。构造方法用来在创建对象时初始化属性名字与类名相同无返回值。this指向当前对象本身用来区分成员变量和参数。内存模型对象在堆中引用在栈中。我们用面向对象的方式重构了“个人名片生成器”感受到了类带来的清晰和便利。面向对象不仅仅是一种编程技术更是一种思维方式。它帮助你从“我需要做什么”的视角转变为“谁来做这件事”的视角。这个转变一旦完成你写程序的方式就再也回不去了。动手试试定义一个Book类包含title书名、author作者、price价格三个属性和一个displayInfo()方法打印书籍信息。然后在main中创建两个Book对象调用方法显示它们的信息。为Book类添加构造方法在创建对象时直接初始化所有属性。定义一个Car类包含brand、color、speed属性以及accelerate()加速速度 10、brake()刹车速度 -10、displayStatus()显示当前速度三个方法。在main中创建一辆车加速几次、刹车几次观察状态变化。用面向对象的方式重新实现“猜数字游戏”把游戏逻辑封装成一个GuessGame类包含target、attempts、guessed等属性以及guess(int num)、isGuessed()、getAttempts()等方法。面向对象的练习非常关键——它不是在练语法而是在练思维。多写几个类你会越来越有感觉。我们下一篇见。 获取本系列示例代码请访问 GitCode。

相关新闻

构建高效离线漫画库:Aidoku下载功能深度解析

构建高效离线漫画库:Aidoku下载功能深度解析

构建高效离线漫画库:Aidoku下载功能深度解析 【免费下载链接】Aidoku Free and open source manga reader for iOS and iPadOS 项目地址: https://gitcode.com/gh_mirrors/ai/Aidoku 你是否曾经在地铁上、飞机上或者网络信号不佳的地方想要阅读漫画却束手无策…

2026/9/30 3:08:49 阅读更多 →
06-03-YooAsset源码-Unity下载系统(DownloadSystem)

06-03-YooAsset源码-Unity下载系统(DownloadSystem)

源码-下载系统(DownloadSystem) 篇章:06-源码深度-文件系统与下载模块 阅读时间:约 30 分钟 前置知识:了解 IFileSystem 一、引言 本章将深入解析 YooAsset 下载系统(DownloadSystem)的源码实现…

2026/10/10 14:04:29 阅读更多 →
Prometheus+Grafana 配置Elasticsearch ,Kafka的启动【Windows环境入门】

Prometheus+Grafana 配置Elasticsearch ,Kafka的启动【Windows环境入门】

Elasticsearch 官网下载:elasticsearch-9.4.3-windows-x86_64.zip 解压 3.修改config/elasticsearch.yml # 本地调试开发单机模式 discovery.type: single-node # 集群模式需要设置 #cluster.initial_master_nodes ["node_1"] # 这几个都改成false访…

2026/10/13 7:02:09 阅读更多 →

最新新闻

Multi-Agent系统Tracing实战:从线上事故到执行链记录体系

Multi-Agent系统Tracing实战:从线上事故到执行链记录体系

1. 从一次线上事故说起:为什么Multi-Agent系统必须做Tracing去年冬天,我们团队上线了一套基于多智能体协作的自动化内容处理系统,四个Agent分别负责信息抽取、逻辑校验、格式转换和最终输出。上线第三天,运营同学反馈说有一批文档…

2026/10/15 5:38:22 阅读更多 →
Java批量生成资产标签PDF:itextpdf配ZXing二维码实战指南

Java批量生成资产标签PDF:itextpdf配ZXing二维码实战指南

上周有位朋友微信找我,说单位三百多台仪器,每年盘点都要两个人蹲在地上逐个抄标签,标签还是买设备时经销商送的,掉了三年没人补。他问我:网上说的“用itextpdf 配合 google.zxing 批量生成资产标签PDF”,到…

2026/10/15 5:38:22 阅读更多 →
Java面试八股文核心真题:并发、JVM、MySQL与Redis深度解析

Java面试八股文核心真题:并发、JVM、MySQL与Redis深度解析

每次面试前,总有人问我Java“八股文”到底要不要背。我的态度很明确:不仅要背,还得背出深度。你光知道synchronized是锁,面试官下一句就是“锁升级过程讲一下”;你光知道HashMap底层是数组加链表,紧接着就是…

2026/10/15 5:38:22 阅读更多 →
Agent Harness工程实战:从循环、上下文到沙箱与验证的稳定运行设计

Agent Harness工程实战:从循环、上下文到沙箱与验证的稳定运行设计

1. 从"能跑"到"跑得住":Harness 工程到底在解决什么很多人第一次接触 Agent 开发,注意力几乎全放在模型本身——提示词怎么写、工具怎么调、输出怎么解析。等真正把 Agent 丢进一个需要连续跑几十分钟甚至几小时的任务里&#xff0c…

2026/10/15 5:38:22 阅读更多 →
用华为云码道 CodeArts 代码智能体,三天从零做出一个全栈 AI 求职平台(附源码)

用华为云码道 CodeArts 代码智能体,三天从零做出一个全栈 AI 求职平台(附源码)

一键开通华为云码道 CodeArts 代码智能体 项目仓库:https://atomgit.com/gcw_93rlw6ed/careerpilot (公开,MIT 协议) 演示账号:打开登录页自动进入(演示账号 candidatedemo.com 自动登录) 一、…

2026/10/15 5:38:22 阅读更多 →
Vue项目实现Office文档在线预览:DOCX、XLSX、PPT一次搞定

Vue项目实现Office文档在线预览:DOCX、XLSX、PPT一次搞定

做前端这几年,被文档预览折磨的次数真不算少。之前接一个合同管理需求,用户提了个特别朴素的要求:附件里的Word合同不要下载到本地再打开,在网页里直接能看就行。我一开始也心想,这有什么难的?不就是嵌一个…

2026/10/15 5:37:22 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →