Java 入门教程(五):面向对象(上)——类与封装
1633 字
8 分钟
Java 入门教程(五):面向对象(上)——类与封装
- 1Java 入门教程(一):JDK、IDEA 与第一个程序
- 2Java 入门教程(二):语法基础与运算符
- 3Java 入门教程(三):流程控制
- 4Java 入门教程(四):方法与数组
- 5Java 入门教程(五):面向对象(上)——类与封装本文
- 6Java 入门教程(六):面向对象(下)——继承、多态与接口
- 7Java 入门教程(七):核心类库——String、包装类与常用工具
- 8Java 入门教程(八):集合框架
- 9Java 入门教程(九):异常处理
- 10Java 入门教程(十):文件 IO 与 NIO
- 11Java 入门教程(十一):多线程与 Lambda
- 12Java 入门教程(十二):Stream API 与综合实战
本篇目标
Java 是纯面向对象语言——一切代码都在类里。本篇讲 OOP 第一支柱封装:类的设计规范、构造方法、this、static 与包管理。Java 的 OOP 比 C++ 更”强制”也更统一。
一、类与对象
第一个正式的类
public class Student { // 成员变量(字段)—— 对象的属性 private String name; private int age; private double score;
// 构造方法 —— 创建对象的入口 public Student(String name, int age, double score) { this.name = name; // this.name 是字段,name 是参数 this.age = age; this.score = score; }
// 无参构造(重载) public Student() { this("未命名", 0, 0); // this(...) 调用另一个构造 }
// getter / setter —— 封装的对外接口 public String getName() { return name; }
public void setAge(int age) { if (age < 0 || age > 150) { // setter 里做校验! throw new IllegalArgumentException("年龄非法: " + age); } this.age = age; } public int getAge() { return age; }
public double getScore() { return score; }
// 成员方法 —— 对象的行为 public void study(String course) { System.out.println(name + " 正在学习 " + course); }
public String introduce() { return String.format("我是%s,%d岁,成绩%.1f", name, age, score); }}public class Main { public static void main(String[] args) { Student ming = new Student("小明", 18, 90.5); // new 创建对象 Student anon = new Student();
ming.study("Java"); System.out.println(ming.introduce()); System.out.println(anon.introduce());
ming.setAge(19); // ✓ 走 setter 校验 // ming.setAge(-1); // 抛 IllegalArgumentException —— 封装的价值 }}对象内存图(理解关键):new 在堆里开辟对象空间,变量 ming 存的是它的引用(地址);多个变量可引用同一对象。
Student a = new Student("小明", 18, 90);Student b = a; // b 和 a 指向同一个对象!b.setAge(20);System.out.println(a.getAge()); // 20System.out.println(a == b); // true(同一地址)JavaBean 规范
字段私有 + 公有 getter/setter + 无参构造——行业通用的数据类写法,IDE 与框架都认这个约定(IDEA 里 Alt+Insert 一键生成)。
二、this 关键字
public class Account { private String owner; private double balance;
public Account(String owner) { this.owner = owner; // ① 区分字段与同名参数 }
public Account(String owner, double balance) { this(owner); // ② this(...) 调用兄弟构造(必须第一行) this.balance = balance; }
public Account deposit(double amount) { if (amount > 0) this.balance += amount; return this; // ③ 返回自身 → 链式调用 }}
new Account("小明", 100).deposit(50).deposit(30);三、封装三私有一公开
// 反例:字段公开public class Bad { public double balance; // 任何代码都能写 account.balance = -999}
// 正例:私有字段 + 校验入口public class Good { private double balance; // 外部不可见
public void deposit(double amount) { if (amount <= 0) throw new IllegalArgumentException("金额必须为正"); balance += amount; // 修改必经校验 } public double getBalance() { return balance; }}封装心法:字段全部 private,外界只通过方法访问——所有修改必须经过你的检查,不变量(余额非负)由类自己守护。
四、static:属于类的成员
public class GameCharacter { // 静态字段:全类共享一份(不属于任何对象) private static int createdCount = 0; static final int MAX_LEVEL = 99; // 静态常量
// 实例字段:每个对象一份 private String name; private int level;
public GameCharacter(String name) { this.name = name; this.level = 1; createdCount++; // 每创建一个 +1 }
// 静态方法:属于类,没有 this(不能访问实例成员!) public static int getCreatedCount() { // System.out.println(this.name); // ❌ 编译错误,静态无 this return createdCount; }
public static void main(String[] args) { new GameCharacter("勇者"); new GameCharacter("法师");
System.out.println(GameCharacter.getCreatedCount()); // 2(用类名调) System.out.println(GameCharacter.MAX_LEVEL); }}静态 vs 实例决策:跟着对象走的(名字、等级)→ 实例成员;全类共享/统计/常量/工具方法 → 静态成员。
main 为什么是 static:程序启动时还没有任何对象,JVM 只能用类名调起入口。
五、包与访问权限
包(package):类的目录组织
// 文件 src/com/club/utils/MathUtils.javapackage com.club.utils; // 第一行声明包(对应目录结构)
public class MathUtils { public static boolean isPrime(int n) { /* ... */ return true; }}
// 使用方import com.club.utils.MathUtils; // 导入
public class Main { public static void main(String[] args) { MathUtils.isPrime(7); }}IDEA 建 com.club.utils 包,把类放进去即可自动管理。
四档访问权限
| 修饰符 | 本类 | 同包 | 子类 | 其他包 |
|---|---|---|---|---|
private | ✓ | |||
| (默认,不写) | ✓ | ✓ | ||
protected | ✓ | ✓ | ✓ | |
public | ✓ | ✓ | ✓ | ✓ |
实用建议:字段 private;方法按需要 public;仅供包内协作的用默认/protected。
六、综合案例:图书借阅系统(封装版)
import java.util.ArrayList;import java.util.List;
public class Library { // ===== 内部数据类 ===== private static class Book { private final String isbn; private final String title; private boolean borrowed;
Book(String isbn, String title) { this.isbn = isbn; this.title = title; } String getTitle() { return title; } String getIsbn() { return isbn; } boolean isBorrowed() { return borrowed; } }
// ===== 业务异常 ===== public static class LibraryException extends RuntimeException { LibraryException(String msg) { super(msg); } }
// ===== 状态封装在 Library 内 ===== private final List<Book> books = new ArrayList<>();
public void addBook(String isbn, String title) { if (findBook(isbn) != null) throw new LibraryException("ISBN 已存在: " + isbn); books.add(new Book(isbn, title)); }
public void borrow(String isbn) { Book b = requireBook(isbn); if (b.borrowed) throw new LibraryException("《" + b.getTitle() + "》已借出"); b.borrowed = true; }
public void giveBack(String isbn) { requireBook(isbn).borrowed = false; }
public void listAll() { System.out.println("—— 馆藏 " + books.size() + " 本 ——"); for (Book b : books) System.out.printf("%-14s %-20s %s%n", b.getIsbn(), b.getTitle(), b.isBorrowed() ? "[借出]" : "[在架]"); }
private Book findBook(String isbn) { // 私有工具方法 for (Book b : books) if (b.getIsbn().equals(isbn)) return b; return null; }
private Book requireBook(String isbn) { Book b = findBook(isbn); if (b == null) throw new LibraryException("无此书: " + isbn); return b; }
public static void main(String[] args) { Library lib = new Library(); lib.addBook("978-7-111", "Java 核心技术"); lib.addBook("978-7-115", "算法(第4版)");
lib.borrow("978-7-111"); lib.listAll();
try { lib.borrow("978-7-111"); // 重复借 } catch (LibraryException e) { System.out.println("❌ " + e.getMessage()); } lib.giveBack("978-7-111"); lib.listAll(); }}设计观察:Book 是 private static 内部类(外界无需知道它的存在)、books 私有(只能通过借/还改变状态)、所有业务错误抛统一异常——这就是封装的完整形态。ArrayList 细节下下篇讲。
小练习
- 实现
RectangleJavaBean:私有宽高 + getter/setter(负数抛异常)+area()/perimeter() - 写
Counter类:静态字段统计创建的对象数、实例方法id()返回自己的序号 - 银行账户
BankAccount:私有余额,deposit/withdraw(不足抛异常)、静态方法统计总账户数与总存款 - 建
com.club.shape包放 Shape 类、com.club.main包写 Main 调用(练习 package/import) - 给 Student 加
compareTo风格方法betterThan(Student other)按成绩比较,main 里造 3 个对象找学霸
本篇小结
- 字段私有 + getter/setter + 无参构造 = JavaBean 规范
- this 三用:区名字 / this(…) 链构造 / 返回自身链式调用
- 引用变量存地址;
==比地址、内容比较用 equals(第七篇详讲) - static 属于类;静态方法无 this 不能摸实例成员
- 四档权限:private → 默认 → protected → public
- 封装的本质:状态私有,修改必经校验
下一篇:面向对象(下)——继承、多态、接口与抽象类,Java OOP 的完全体。
本系列为 Cyber先锋社原创教程。IDEA 的 Alt+Insert(生成 getter/setter/构造)先练熟,生产力 ×10。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Java 入门教程(五):面向对象(上)——类与封装
https://www.cyberpioneer.club/posts/java-tutorial-05/相关文章智能推荐
1
C++ 入门教程(八):面向对象(上)——类与封装
C++ 教程深入 C++ 类:class 与 struct 的区别、访问控制 public/private/protected、构造函数与初始化列表、析构函数、拷贝构造与拷贝赋值、深浅拷贝问题、static 成员与 this 指针。
2
Java 入门教程(六):面向对象(下)——继承、多态与接口
Java 教程讲透 Java OOP 完全体:继承与 super、方法重写规则、多态与动态绑定、抽象类、接口(默认/静态方法)、Object 核心方法(equals/hashCode/toString)、final 三用法与组合原则。
3
Java 入门教程(四):方法与数组
Java 教程掌握 Java 方法定义与重载、可变参数、值传递本质、数组全操作(声明/遍历/工具类 Arrays/二维数组)、命令行参数与 main 签名,附数组统计与矩阵转置实战。
4
Java 入门教程(二):语法基础与运算符
Java 教程详解 Java 基本语法:注释、变量与常量、八种基本类型与类型转换规则、七类运算符、Scanner 输入进阶与 printf 格式化,配典型陷阱与对照示例。
5
Java 入门教程(一):JDK、IDEA 与第一个程序
Java 教程进入 Java 的世界:理解"一次编写,到处运行"的原理、安装 JDK 与 IDEA、解剖第一个程序的结构、掌握变量与数据类型。企业级开发语言的起点。
随机文章随机推荐



