- xianaldai2026-08-1110677
本期是Java开发教程系列的第二期,本期主要向各位介绍 Java 面向对象的基础知识——*类与对象*.若你已经了解类和对象的基本概念,可以跳过本期内容.
*每期叠甲*:
时间仓促,水平有限,文中难免存在缺点和错误,恳请广大开发者和从业者指正.
*一、为什么需要类和对象*
第 1 期我们学了变量、方法、数组和集合.但如果要描述"一堆学生",每个学生的姓名、成绩都单独定义变量,代码很快会变成灾难:```
String name1 = "小明";
double score1 = 92;
String name2 = "小红";
double score2 = 88;
// 如果有一百个学生呢?这样写根本没法维护,也就是俗称的史山代码.
```我们需要一种把"相关的数据 + 相关的操作"打包在一起的方式.Java 用*类*(class)和*对象*(object)来做这件事:- *类* = 一张*图纸*,规定了这一类东西"长什么样、能干什么"
- *对象* = 按图纸*造出来的具体东西*;同一张图纸,可以造出无数个对象
打个比方:
Student类是"学生"的模板,而"小明""小红"是按这个模板造出来的具体对象——每个对象有自己的姓名、成绩,但结构(有哪些字段、哪些方法)都一样.*二、定义类:字段与方法*
*2.1 一个最简单的类*
用代码定义一个"学生"类:```
public class Student {
// 字段(也叫属性):描述学生"是什么样"
String name; // 姓名
double score; // 成绩
// 方法:描述学生"能干什么"
void sayHello() {
System.out.println("你好,我是 " + name);
}
}
``-public class Student声明一个公开的类,类名是Student`- 类里面的
name、score叫*字段*,保存这个对象的"状态"-
sayHello()是*方法*,定义这个对象的"行为"- 注意:这些代码目前是*定义*,什么都没运行
*2.2 使用对象:new*
题外话:这也是有时候说找不到对象就new一个的原因.
要在程序里真正用上,得先*造一个对象*出来,用
new:```public class Main {
public static void main(String[] args) {
Student s1 = new Student(); // 用 new 造出一个学生对象
s1.name = "小明"; // 给字段赋值
s1.score = 92;
s1.sayHello(); // 调用方法
System.out.println(s1.score);
}
}
``运行结果:``你好,我是 小明
92.0
``-new Student()就是****创建对象****,s1` 是一个指向这个对象的引用- 通过
s1.字段名读/写字段,通过s1.方法名()调方法- 一个类可以造出任意多个互不干扰的对象:再写
Student s2 = new Student();,s2是另一个学生*三、构造方法*
*3.1 为什么需要构造方法*
上面的写法要
s1.name = "小明"; s1.score = 92;两行才设置好初始值,麻烦.用*构造方法*(constructor)可以在*创建对象的同时*把初始值填好:```
public class Student {
String name;
double score;
// 构造方法:方法名和类名一模一样,而且不写返回类型
Student(String name, double score) {
this.name = name;
this.score = score;
}
}
``使用方式立刻清爽了:``Student s1 = new Student("小明", 92); // 创建的同时就初始化好了
Student s2 = new Student("小红", 88);
```构造方法的三条规则:- 方法名*必须和类名一样*(包括大小写)
- *不写返回类型*(连
void都不写)- 通过
new调用,不需要也不能手动调用*3.2 无参构造与有参构造*
- 如果你*一个构造方法都没写*,编译器会免费送一个*无参构造*,它什么都不干,字段保持默认值(数字是 0、引用是 null)
- 一旦你*自己写了构造方法*,免费的无参构造就*消失*了.此时再写
new Student()会编译报错——除非你显式再补一个无参构造:```public class Student {
String name;
double score;
// 无参构造
Student() {
}
// 有参构造
Student(String name, double score) {
this.name = name;
this.score = score;
}
}
``这样new Student()和new Student("小明", 92)` 都能用.两个构造方法名字相同、参数不同,这正是第 1 期讲过的*方法重载*的典型应用.*四、this 关键字*
this只有一个含义:*“当前这个对象”*.你可以把它想成对象的名片——谁在跑这段代码,this就是谁.*4.1 它在构造方法里做什么*
再看刚才的构造方法:```
Student(String name, double score) {
this.name = name;
this.score = score;
}
``执行new Student("小明", 92)时,this就是那个新造出来的"小明"对象.这行代码里出现了****两个****name`,它们不是一回事:- 右边的
name:是*参数*.参数就在最近的括号里,所以不带this的name默认指它- 左边的
this.name:是*字段*.前面加了this,明确说"这个对象的字段"所以
this.name = name;的意思就是:*把传进来的参数 name,存进当前对象的 name 字段里*.这里藏着一条新手最容易懵的规则: *就近原则* :不带
this的name,先找参数,找到就指参数,参数里没有才去找字段.构造方法里参数和字段恰好同名,所以必须靠this才能指到字段.*4.2 为什么参数要和字段同名*
其实换成别的名字也能写:```
Student(String n, double s) {
this.name = n;
this.score = s;
}
``参数叫n/s当然可以,但这样看不出"这个参数是给哪个字段用的".更常见的习惯是****参数和字段同名****,再用this区分——一眼就知道name要存进name,score要存进score`.所以这不是必须的语法,而是一种让代码更好读的写法.*4.3 新手速记*
this不只出现在构造方法里,但新手阶段只需要记住构造方法里这一个用法——参数和字段同名时,this.字段指字段.普通方法里没有同名参数,this通常不用写,现在先别管它.*五、一个文件一个公开类*
这里有个新手常搞混的点,先划重点:*被限制的是"public 类"的个数,不是"public 成员"的个数*.
- 一个
.java文件里*只能有一个 public 类*,而且这个类的名字*必须和文件名一模一样*(大小写也要一致)- 但*一个类内部可以有任意多个 public 成员*——多个 public 字段、多个 public 方法都没问题:```
public class Student { // 文件里唯一的 public 类,必须和文件名 Student.java 一致
public String name; // public 字段,可以有多个
public double score;
public void sayHello() { // public 方法,也可以有多个
System.out.println("你好,我是 " + name);
}
}
``- 同一个文件里还能放****不加 public 的辅助类****,但不能再放第二个 public 类:``public class Main {
public static void main(String\[\] args) {
Helper h = new Helper();
h.go();
}
}
// 同一个文件里可以放非 public 的类,但不能再加一个 public 的
class Helper {
void go() {
System.out.println("我是辅助类");
}
}
```如果文件名和 public 类名不一致,编译器会直接报错.为什么这么规定?为了让编译器能快速找到类:它要找
Student,直接去Student.java找就行,不用把整个项目的文件都扫一遍.这个习惯要记牢,后面写工程都是这个规则.*六、三元运算符*
接下来介绍一个第 1 期没讲过的小语法——*三元运算符*
条件 ? 值A : 值B:```String result = score >= 60 ? "及格" : "不及格";
``意思是:条件成立(为 true)就取?后面的值,不成立就取:后面的值.上面这行等价于:``String result;
if (score >= 60) {
result = "及格";
} else {
result = "不及格";
}
```看到区别了吗?三元运算符就是把最简单的 if/else 压缩成一行,适合"根据一个条件选一个值"的场合.分支一多就不要用它,可读性会变差.接下来的小项目你就可以试一试三元运算符.*七、小项目:学生成绩统计*
把本期内容串成一个能运行的小程序,共两个文件.
文件一
Student.java:```public class Student {
String name;
double score;
// 构造方法:创建对象时初始化
Student(String name, double score) {
this.name = name;
this.score = score;
}
// 判断是否及格
boolean passed() {
return score >= 60;
}
// 格式化打印自己
void printInfo() {
System.out.println(name + " 成绩 " + score
+ (passed() ? " 及格" : " 不及格"));
}
}
``文件二Main.java:``public class Main {
public static void main(String\[\] args) {
// 创建三个学生对象
Student a = new Student("小明", 92);
Student b = new Student("小红", 58);
Student c = new Student("小刚", 76);
// 把对象装进数组,逐个打印
Student\[\] students = {a, b, c};
for (Student s : students) {
s.printInfo();
}
// 计算平均分
double sum = 0;
for (Student s : students) {
sum += s.score;
}
System.out.println("平均分:" + sum / students.length);
// 找出最高分
Student best = students\[0\];
for (Student s : students) {
if (s.score > best.score) {
best = s;
}
}
System.out.println("最高分:" + best.name);
}
}
``运行结果:``小明 成绩 92.0 及格
小红 成绩 58.0 不及格
小刚 成绩 76.0 及格
平均分:75.33333333333333
最高分:小明
``这个小程序用到了第 1 期的数组和增强for,加上本期的类和对象.注意看students数组里装的****不是数据,而是对象的引用****——数组students[0]、students[1]、students[2]分别指向三个Student` 对象.*朝花夕拾:现在能看懂第 1 期的 File 了*
第 1 期我们写过这样一行:```
File myFile = new File(new xxxxxx);
```当时说它"有问题",但没说清问题在哪.学完本期,你能看懂一大半了:-
new是*创建对象*,new File(...)就是创建一个File对象-
new xxxxxx之所以写不出来,是因为File的构造方法接收的是一个*路径字符串*,不是另一个对象.正确写法是:```File myFile = new File("D:\\mc\\mod\\config.txt");
``其实File本身就是一个类,myFile就是一个File` 对象——对象,正是本期学的核心概念.*总结*
本期我们迈出了面向对象的第一步:
- *类与对象*:类是图纸,对象是按图纸造出来的实体;一个类能造出无数个对象
- *字段与方法*:字段描述对象"是什么样",方法描述对象"能干什么"
- *构造方法*:创建对象时初始化;方法名和类名相同、不写返回类型;一旦写了有参构造,无参构造就没了
- *this*:区分字段和同名参数
- *一个文件一个公开类*:public 类名必须和文件名一致
掌握这些,就能用"类"把相关的数据和操作组织起来了.下一期我们将学习*分包、注释与访问控制*——讲清楚类与类之间怎么组织、谁能访问谁.
主楼 - wintsa2026-08-1110534
此帖子已被社区举报,现已被临时隐藏。
- 晚上要做白日梦2026-08-1164372
好学 ^-^,爱学 ^-^,期待下一节 ^-^
- 冷月映秋风2026-08-115738
- 此门不通2026-08-1160912
我很难想象这种发言会出现在L站里 ^-^
- 当且仅当2026-08-1111559
我去,梦回十年前,好有感觉,我的青春回来了
- tero2026-08-119241
今夕是何年,竟然还能在这看到这么熟悉又陌生的东西
- xianaldai2026-08-1110677
佬友提了一个很有意思的问题,我觉得您的问题可以换成另一种说法:大家都在用模型生成大段代码的时代,传统的编程语言教学还有意义吗?
我觉得是有的.
既然大家都在用模型来生成代码,没有谁比谁出彩,因而大家都只是在所谓的平均水平徘徊.
这个时候,如果你能发现模型生成代码存在的某些小错误,甚至是某些安全功能:限流/熔断/数据清洗等等做的不到位的地方,有安全隐患的地方,这就是你的能力了
换一个方面,模型生成代码不总是对的,人类永远是模型代码最后的面壁人.ai写的代码含有安全漏洞的概率,统计学上比人类从业者要高得多.
不积跬步,无以至千里,我认为打好基础是迈向ai新时代的必要一步
- 纸雨2026-08-1163111
死去的回忆又出现了,我不想想起来呀,我有gpt了
- xianaldai2026-08-1110677
- 7522026-08-118352
老师老师能不能讲讲八股文这些对于我现在来说太遥远了 ^-^
- 纸雨2026-08-1163111
支持楼主哦,有人会需要的,谁不是看这玩意过来的
- xianaldai2026-08-1110677
你指的是各个框架还有23种设计模式吗?估计比较靠后了,先得教完全部基础 ^-^
- 51烦2026-08-1164373
依旧是小明,但有种时代变了的感觉 ^-^
- xianaldai2026-08-1110677
本来想写张三的但是感觉不太好,最后还是用数学书上的命名吧
- taku2026-08-1136316
分配对象需要空间的,如果你没有大house, 分配的对象也是会被回收的