news 2026/10/27 2:00:36

Java 面向对象编程(二):包、封装、static 关键字与代码块详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 面向对象编程(二):包、封装、static 关键字与代码块详解

Java SE 学习笔记 · 面向对象基础篇(二)

前言

在上一篇文章中,我们学习了 Java 面向对象的基本概念,包括类与对象、成员变量、成员方法、this关键字以及构造方法。

但是随着项目规模逐渐增大,仅仅会创建对象还远远不够。我们还需要解决以下问题:

  • 如何将不同功能的类分类管理?

  • 如何限制外部代码对对象内部数据的访问?

  • 多个对象需要共享相同的数据怎么办?

  • 静态方法与普通成员方法有什么区别?

  • 创建对象时,静态代码块、实例代码块和构造方法按照什么顺序执行?

本文结合代码示例,系统整理这些知识。

一、Java 包

1.1 什么是包?

在java中,包是一种组织和管理类,接口(这个可以先不用理解,后面再说)等类型的机制

简单理解为:文件夹

例如我们做了一个项目

JavaProject ├── Student.java ├── Teacher.java ├── Computer.java └── Main.java

可以看到这个项目包含了很多类,但是如果类多了起来,我们这个项目就会变得难以管理

这时候就需要包,对这些负责不同功能的类进行分类管理

比如

src └── com └── example ├── student │ └── Student.java ├── computer │ └── Computer.java └── main └── Main.java

那么说了那么多,包有什么作用呢?

包主要有三个作用:

  1. 1:组织和管理不同功能的类。★★★

  2. 2:避免不同包之间的类名冲突。

  3. 3:配合访问修饰符,实现访问权限控制。

1.2 package关键字

例如

package com.example.student; public class Student { String name; int age; }

package声明必须位于 Java 源文件的前部,在普通import和类型声明之前。

包名通常使用小写字母,常见命名方式为反向域名。

例如

package com.example.demo;

对应的文件目录为

com/example/demo/

1.3 import关键字

当我们需要使用其他包中的类时,可以通过import导入。

例如

import java.util.Date; public class Main { public static void main(String[] args) { Date date = new Date(); System.out.println(date.getTime()); } }

当然,这里特殊介绍一种

import java.util.*;

这样子,可以访问这个包中所有的类

但是实际项目,我们更应该明确导入需要使用的类,不仅是为了更加清晰,更是为了减少类名冲突


二 java的封装

2.1 什么是封装

封装是 Java 面向对象编程的三大基本特性之一。

另外两个分别是继承和多态(后面再说)。

封装的核心思想可以概括为:

将对象的数据和操作数据的方法组织在一起,隐藏内部实现细节,只提供必要的对外访问接口。

可以用电脑来理解。

对于电脑使用者而言,只需要知道:

  • 1:如何开机

  • 2:如何关机

  • 3:如何使用键盘

  • 4:如何通过屏幕查看信息

至于 CPU 内部如何工作、主板线路如何设计,普通使用者并不需要了解。

在 Java 编程中,也可以采用类似的设计思想。这就是封装

2.2 为什么需要封装

假设定义一个学生类:

class Student { public String name; public int age; }

外部可以直接修改成员变量:

Student s = new Student(); s.name = "张三"; s.age = -100;

虽然可以,但是这个年龄显然不符合实际要求

所以我们更希望限制外部代码对成员变量的直接修改

2.3 private关键字

使用private修饰成员变量:

class Student { private String name; private int age; }

此时,在其他类中不能直接访问这些字段:

Student s = new Student(); s.age = 18; // 编译错误

因为age是私有成员,只可以在student这个类内部中直接访问,不可以在其他地方访问

需要注意,private限制的是类级别的访问,而不是只能由某一个对象访问。

同一个类中的方法,可以通过其他同类对象的引用访问其私有字段。

2.4 getter 与 setter 方法

为了让外部能够合理访问属性,我们可以提供公共方法。

class Student { private String name; private int 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; } }

在其他类中

public class Main { public static void main(String[] args) { Student s = new Student(); s.setName("张三"); s.setAge(18); System.out.println(s.getName()); System.out.println(s.getAge()); } }

输出:

张三 18

这里有两个重要概念:

getter:读取对象属性。

setter:修改对象属性。

2.5 setter 的真正价值

或许有人问,这样是不是脱裤子放屁--多此一举,其实并不是,通过setter调用

更重要的是:我们可以在公共方法中控制数据的合法性。

例如:

public void setAge(int age) { if (age >= 0 && age <= 150) { this.age = age; } else { System.out.println("年龄不合法!"); } }

这样可以避免随意修改对象状态。

对于某些不允许外部修改的数据,甚至可以只提供 getter,而不提供 setter。

2.6 封装的优点

优点说明
降低耦合性外部不需要了解类的内部实现
降低复杂性只暴露必要的操作接口
提高安全性防止对象状态被随意修改
提高可维护性内部实现改变时,可以尽量保持公共接口稳定

需要注意,封装的主要目的并不是提高程序运行速度,而是改善代码设计和维护性。

三 java访问修饰符

Java 提供四种常见的成员访问权限:

  • 1:public

  • 2:protected

  • 3:默认访问权限(不写修饰符)

  • 4:private

下面我们来列表介绍区别

3.1 访问权限对比

访问范围publicprotected默认权限private
同一个类✓✓✓✓
同包其他类✓✓✓✗
不同包的子类✓有条件✗✗
不同包的普通类✓✗✗✗

这里,我们只了解public,默认权限,private即可

我们可以类比,在这里,类指自己,包指家人

public相当于你对外界公开的信息,比如你的性别等等

默认权限,就是指你和你的家人都知道的信息

private,就是指只有你自己知道的信息

3.2 默认访问权限

例如:

class Student { String name; }

name没有显式指定访问修饰符。

此时,它使用默认访问权限,也叫包访问权限(package-private)。

同包中的其他类可以访问,其他包中的普通类不能直接访问。

3.3 跨包访问示例

看了那么多理论性的东西,下面我们给出一个简单的例子方便大家更好的理解

假设项目结构如下:

com.example ├── model │ └── Computer.java └── app └── Main.java

Computer.java

package com.example.model; public class Computer { private String cpu; public String screen; String brand; public Computer(String cpu, String screen, String brand) { this.cpu = cpu; this.screen = screen; this.brand = brand; } public String getCpu() { return cpu; } }

Main.java

package com.example.app; import com.example.model.Computer; public class Main { public static void main(String[] args) { Computer computer = new Computer("M4", "Retina", "Apple"); System.out.println(computer.screen); // System.out.println(computer.cpu); // System.out.println(computer.brand); System.out.println(computer.getCpu()); } }

问题:

Q1:为什么 Main.java 要使用 import?

Q2:为什么 computer.screen 可以访问,而 computer.cpu 不能?

Q3:为什么 computer.brand 不能访问?

Q4:为什么 private 修饰的 cpu 可以通过 getCpu() 获取?

Q5:new Computer("M4", "Retina", "Apple") 有什么作用?

大家可以尝试做做这个5个问题,答案会在文末提出,谢谢!

四:static关键字

4.1 static 是什么?

static可以修饰成员变量和成员方法。

被static修饰的成员称为静态成员,也叫类成员。

静态成员属于类,而不是某一个具体对象。

4.2 普通成员变量和静态成员变量

假设定义一个学生类:

class Student { String name; static String classRoom = "1-101"; }

假如我们要创建多个对象

Student s1 = new Student(); Student s2 = new Student(); Student s3 = new Student(); s1.name = "张三"; s2.name = "李四"; s3.name = "王五";

此时,每个对象有自己的name,但是classRoom是被整个Student类共享

4.3 静态变量的访问

可以通过类名直接访问

System.out.println(Student.classRoom);

输出:

1-101

如果修改成1-114514,

那么将会输出 1-114514.

4.4 static 的实际用途

一个常见用途是统计对象创建次数。

class Student { private static int count = 0; public Student() { count++; } public static int getCount() { return count; } }

调用

public class Main { public static void main(String[] args) { Student s1 = new Student(); Student s2 = new Student(); Student s3 = new Student(); System.out.println(Student.getCount()); } }

输出

3

通过静态变量,我们可以记录这个类累计创建了多少个对象。

需要注意,这段示例只统计构造方法执行的次数,不等于当前仍然存活的对象数量。

五:static静态方法

5.1 静态方法的定义

public static 返回值类型 方法名() { // 方法体 }

例如

class MyMath { public static int max(int a, int b) { return a > b ? a : b; } }

使用时

int result = MyMath.max(10, 20); System.out.println(result);

静态方法通常适合实现不需要依赖某个具体对象状态的功能。

注意:静态方法不可以直接访问非静态成员

5.2静态方法能否使用对象?

class Student { String name; public static void show() { Student student = new Student(); student.name = "张三"; System.out.println(student.name); } }

这是合法的。

因为静态方法虽然没有自己的this,但可以创建对象,并通过明确的对象引用访问实例成员。

因此应该准确理解为:

静态方法不能直接访问实例成员,但可以通过对象引用访问允许访问的实例成员。

同时,静态方法一样不可以用this,注意!!!

5.3 静态成员和实例成员对比

比较静态成员实例成员
所属类对象
推荐访问方式类名.成员对象.成员
是否由对象分别拥有否是
是否需要当前对象不需要需要
静态方法中直接访问可以访问可见的静态成员不能直接访问
使用 this静态方法中不允许实例方法中允许

六 代码块

6.1 什么是代码块

我们称{}包围起来的一段代码称为代码块

可以分为以下几类
1:普通代码块
2:实例代码块
3:静态代码块
4:同步代码块

在本篇文章只介绍前3种

6.2 普通代码块

普通代码块可以定义在方法内部

例如

public class Main { public static void main(String[] args) { { int x = 10; System.out.println(x); } int x = 100; System.out.println(x); } }

输出

10 100

可以看见,普通代码块可以形成一个局部作用域

在上面的例子中,第一个x的作用域随着内部代码块结束而结束,因此后面可以重新声明x。

6.3 实例代码块

例如

class Student { String name; { name = "张三"; System.out.println("实例代码块执行"); } public Student() { System.out.println("构造方法执行"); } }

创建对象:

Student s = new Student();

输出

实例代码块执行 构造方法执行

他有一个重要特点,就是:

每创建一个对象,实例代码块就会执行一次。

6.4 静态代码块

静态代码块通过static定义:

class Student { static String school; static { school = "机密大坝"; System.out.println("静态代码块执行"); } }

静态代码块通常用于初始化静态成员。

他只会执行一次

6.5 静态代码块与实例代码块的区别

比较静态代码块实例代码块
定义形式static {}{}
执行时机类初始化时每次对象初始化时
执行次数每次类初始化一次每创建一个对象执行一次
是否可以使用 this不可以可以
常见用途初始化静态数据初始化实例数据

下面介绍一下这三种代码块的执行顺序

大家可以把这一段代码运行一下

class Student { static { System.out.println("1. 静态代码块"); } { System.out.println("2. 实例代码块"); } public Student() { System.out.println("3. 构造方法"); } } public class Main { public static void main(String[] args) { Student s1 = new Student(); System.out.println("=========="); Student s2 = new Student(); } }

输出的是

1. 静态代码块 2. 实例代码块 3. 构造方法 ========== 2. 实例代码块 3. 构造方法

可以看见,静态的代码块只会执行一次,第二次创建新的对象时,不会再执行

通常三种代码块的执行顺序是

静态字段显式初始化 / 静态代码块 ↓ 实例字段显式初始化 / 实例代码块 ↓ 构造方法主体

最后的总结

本章主要学习了 Java 类与对象的进一步知识。

其中最重要的内容可以归纳为五点:

1. package 与 import 用于组织和使用不同包中的类。

合理划分包能够提升项目结构的清晰度。

2. 封装的重点是隐藏实现细节、控制对外访问。

private 与公共方法只是实现封装的常见手段。

3. 访问权限决定不同位置的代码能否访问成员。

需要理解 public、private、默认访问权限和 protected 的区别(先不用理解protected)。

4. static 成员属于类,而不是某个具体对象。

静态变量适合保存共享数据,静态方法适合实现不依赖实例状态的功能。

5. 静态代码块、实例代码块和构造方法具有不同的初始化时机。

理解它们的执行顺序,有助于阅读代码和排查初始化问题。

我们下节再见!

2026.10.26 11:09

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 2:00:12

电力市场EM01 | N002 什么是电力市场?一文看懂国内电力市场底层逻辑

摘要&#xff1a;本文沿着国内电改时间线&#xff0c;从计划管理模式、两轮关键电改节点切入&#xff0c;通俗讲解电力商品独有的物理约束、电力市场五大交易板块、各参与主体权责&#xff0c;同时厘清市场对工商业企业与普通居民的影响&#xff0c;梳理常见认知误区&#xff0…

作者头像 李华
网站建设 2026/10/27 2:00:07

在 C# 中,单元测试聚焦于隔离验证单个方法或类的逻辑,不依赖数据库、网络等外部资源;集成测试则验证多个组件(如 API、数据库、中间件)协同工作是否正常

在 C# 中&#xff0c;单元测试聚焦于隔离验证单个方法或类的逻辑&#xff0c;不依赖数据库、网络等外部资源&#xff1b;集成测试则验证多个组件&#xff08;如 API、数据库、中间件&#xff09;协同工作是否正常。两者通常分属不同的测试项目&#xff0c;使用 MSTest、xUnit 或…

作者头像 李华
网站建设 2026/10/27 1:59:38

【电子通识】UV固化三防涂层过了UV灯就万事大吉了?

UV灯亮了&#xff0c;涂层就固化“好了”&#xff1f;干了这么多年硬件&#xff0c;我发现最容易骗过自己的就是眼睛做工程久了&#xff0c;会养成一种职业病&#xff1a;相信“过了设备”就等于“做完了” 。PCB从回流焊里出来&#xff0c;过了就是焊好了。从清洗机里出来&…

作者头像 李华
网站建设 2026/10/27 1:58:50

从财务呈现到经营导航:FPA正助力企业摆脱滞后管理

当外部环境从增量扩张转向存量博弈&#xff0c;传统财务计划与分析&#xff08;FP&A&#xff09;职能正被迫经历一场变革。它不再只是年底关账后的“数据整理员”&#xff0c;而是被推到了战略决策的中心舞台&#xff0c;成为业务方向的塑造者与决策质量的赋能者。这种从被…

作者头像 李华
网站建设 2026/10/27 1:58:12

与服务器之间的文件传输工具全整理:常用工具与安装包下载地址

一、为什么需要专门的文件传输工具 在日常运维、开发和部署过程中&#xff0c;我们经常需要在本地电脑与远程服务器之间来回搬运文件&#xff1a;上传代码包、下载日志、同步配置文件、备份数据库导出结果等。虽然 scp、sftp 这类命令行工具已经能满足基本需求&#xff0c;但在…

作者头像 李华
网站建设 2026/10/27 1:57:26

行测—言语理解

第一部分 中心理解题一、提问方式这段文字主要/旨在/重在/意在/想要说明&#xff08;论述/强调&#xff09;的是......这段文字的主旨/主题/观点是......对这段文字概括最恰当的是......这段文字表达了作者......从这段文字中我们可以看出作者的意圈/态度是......这段文字出自一…

作者头像 李华