1. POP 与 OOP#
- 二者都是一种思想,面向对象是相对于面向过程而言的。
- 面向过程,强调的是功能行为,以“函数”为最小单位,考虑怎么做。
- 面向对象,将功能封装进对象,强调的是具备了功能的对象,以“类/对象”为最小单位,考虑谁来做。
- 例子:人把大象装进冰箱

2. 类和对象#
- 用引用操纵对象(对象是实际存在的该类事物的每个个体,因而也称为实例)

- 永远不需要销毁对象

- 创建新的数据类型:类(类是对一类事物的描述,是抽象的、概念上的定义)

- 一切皆对象
- 在 Java 语言范畴中,我们都将功能、结构封装到类中,通过类的实例化来调用具体的功能结构。
- 涉及到 Java 语言与前端 HTML、后端的 DB 交互时,前后端的结构映射到 Java 层面,都体现为类和对象。
3. 类及类的成员#
- 面向对象程序设计的重点是类的设计,而类的设计,其实就是类的成员的设计。在类中可设置两种类型的元素:字段(成员变量)和方法(成员函数)
- 字段可以是任何类型的对象,可以通过其引用与其进行通信
- 方法决定了一个对象能够接受什么样的消息,调用方法的行为通常被称为"发送消息给对象" // 面向对象的程序设计通常简单地归纳为"向对象发送消息"
- 类的语法格式

- 对象的创建和使用

- 为对象赋值
- 在对一个对象进行操作时,我们真正操作的是对对象的引用
- 倘若"将一个对象赋值给另一个对象",实际上是将"引用"从一个地方复制到另一个地方
- 相同的引用指向相同的对象,如下代码中
p3 = p1
,那么 p3 和 p1 都指向原本只有 p1 指向的那个对象
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
Person p3 = p1;
p1.name = "tom";
p1.isMale = true;
System.out.printf("%s, %d, %b\n", p1.name, p1.age, p1.isMale);
System.out.printf("%s, %d, %b\n", p2.name, p2.age, p2.isMale);
p3.age = 10;
System.out.printf("%s, %d, %b\n", p1.name, p1.age, p1.isMale);
p1.eat();
p1.talkTo("jerry");
}
}
class Person {
String name;
int age = 1;
boolean isMale;
public void eat() {
System.out.println("eat chips");
}
public void talkTo(String name) {
System.out.println("和" + name + "说话");
}
}
4. 内存解析#



5. 局部变量和成员变量的区别#
- 在类中的位置不同
- 成员变量:在类中方法外
- 局部变量:方法内部、方法声明、代码块内
- 在内存中的位置不同
- 成员变量:在堆内存(! static) // staticVar 在方法区
- 局部变量:在栈内存
- 生命周期和管理方式不同
- 成员变量:随着对象的创建而存在,随着对象的消失而消失
- 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
- 初始化值不同
- 成员变量:有默认初始化值
- 基本类型

- 引用类型(类、数组、接口):null
- 局部变量:没有默认初始化值,必须显式赋值才能使用,否则会在编译时报错
- 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则
- 小结

6. 对象数组#
- 定义类 Student,包含三个属性:学号 number(int),年级 state(int),成绩 score(int)。 创建 20 个学生对象,学号为 1 到 20,年级和成绩都由随机数确定
- Q1:打印出 3 年级(state 值为 3)的学生信息
- Q2:使用冒泡排序按学生成绩排序,并遍历所有学生信息
- 引用类型的元素组成的数组在使用过程中存在二级的指向关系


public class StudentTest {
public static void main(String[] args) {
Student[] stuArr = new Student[20];
int score, state;
for (int i = 0; i < stuArr.length; i++) {
state = (int) (Math.random()*4)+1;
score = (int) (Math.random()*101);
stuArr[i] = new Student();
stuArr[i].number = i+1;
stuArr[i].state = state;
stuArr[i].score = score;
if (stuArr[i].state == 3) System.out.println(stuArr[i].getInfo());
}
for (int i = stuArr.length - 1; i>0; i--)
for (int j = 0; j < i; j++)
if (stuArr[j].score > stuArr[j+1].score) {
Student stu = stuArr[j];
stuArr[j] = stuArr[j+1];
stuArr[j+1] = stu;
}
for(int i = 0; i < stuArr.length; i++)
System.out.println(stuArr[i].getInfo());
}
}
class Student {
int number;
int state;
int score;
public String getInfo() {
return "number=" + number + ", state=" + state + ", score=" + score;
}
}
7. 匿名对象#
- 创建对象时,只有创建对象的语句,却没有把对象地址显式的赋值给一个引用变量
- 虽然是创建对象的简化写法,但是应用场景非常有限,一个匿名对象只能使用一次
- 使用:
new 类名(参数列表)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?