07 面向对象:类与封装¶
本章目标¶
- 理解类与对象的概念
- 掌握属性、方法、构造器
- 掌握 this、static
- 理解封装:private / getter / setter
7.1 什么是面向对象?¶
把现实世界的东西抽象成类(Class),用类创建对象(Object)。
- 类:模板 / 图纸。比如"玩家"是一个类,定义了所有玩家共有的属性和行为
- 对象:根据图纸造出来的具体实例。比如"小明这个玩家"是一个对象
类:玩家(Player)
├── 属性:名字、等级、血量
└── 行为:攻击()、移动()、升级()
对象:小明的玩家角色(名字=小明, 等级=30, 血量=80)
模组开发全是面向对象:Item、Block、Entity、BlockEntity 都是类,你创建的具体物品/方块是它们的子类实例。
7.2 定义一个类¶
public class Player {
// 属性(成员变量)
String name;
int level;
int hp;
// 行为(成员方法)
void attack() {
System.out.println(name + " 发动攻击!");
}
void levelUp() {
level++;
System.out.println(name + " 升到 " + level + " 级!");
}
}
7.3 创建对象(实例化)¶
用 new 类名() 创建对象:
public class Main {
public static void main(String[] args) {
Player p1 = new Player(); // 创建对象
p1.name = "小明";
p1.level = 1;
p1.hp = 20;
p1.attack(); // 调用对象的方法
p1.levelUp();
}
}
对象 = 引用
p1 是引用类型变量,指向内存里的对象。new 就是在内存里开辟一块空间放这个对象。
7.4 构造器(Constructor)¶
构造器:创建对象时自动执行的特殊方法,用来初始化属性。
public class Player {
String name;
int level;
int hp;
// 构造器:方法名和类名相同,没有返回值
public Player(String name, int level, int hp) {
this.name = name;
this.level = level;
this.hp = hp;
}
}
// 使用
Player p = new Player("小明", 30, 80);
this 关键字¶
this 指"当前对象自己",用来区分成员变量和参数(同名时):
public Player(String name, int level, int hp) {
this.name = name; // 左边是成员变量,右边是参数
this.level = level;
}
构造器重载 + 默认构造器¶
public Player() { // 无参构造器
this("无名", 1, 20); // 调用另一个构造器
}
public Player(String name) { // 一个参数的构造器
this(name, 1, 20);
}
public Player(String name, int level, int hp) {
this.name = name;
this.level = level;
this.hp = hp;
}
注意
如果你不写任何构造器,Java 会给你一个默认无参构造器;一旦你写了带参构造器,默认无参构造器就没有了(需要自己补)。
7.5 封装:private 与 getter/setter¶
封装:属性设为 private(只有类内部能访问),通过公开方法读写。防止别人把数据改坏。
public class Player {
private String name;
private int level;
private int hp;
public Player(String name, int level, int hp) {
this.name = name;
this.level = level;
this.hp = hp;
}
// getter:读取
public String getName() { return name; }
public int getLevel() { return level; }
public int getHp() { return hp; }
// setter:修改(可以加校验)
public void setHp(int hp) {
if (hp < 0) hp = 0; // 不允许负血量
this.hp = hp;
}
public void takeDamage(int dmg) {
setHp(this.hp - dmg);
if (this.hp == 0) {
System.out.println(name + " 倒下了!");
}
}
}
调用:
Player p = new Player("小明", 30, 80);
p.setHp(-100); // 会被拦下来变成 0
System.out.println(p.getHp()); // 0
IDE 快速生成
IDEA 里右键 → Generate → Getter and Setter,一键生成。
7.6 static 关键字¶
static 成员属于类本身,不属于某个对象,用 类名. 访问:
public class GameConfig {
static final String SERVER_NAME = "FFS 永恒落英";
static int onlinePlayers = 0;
static void playerJoined() {
onlinePlayers++;
}
}
// 使用:不需要 new
System.out.println(GameConfig.SERVER_NAME);
GameConfig.playerJoined();
System.out.println(GameConfig.onlinePlayers); // 1
| static 成员 | 实例成员 | |
|---|---|---|
| 属于 | 类 | 对象 |
| 访问 | 类名.xxx |
对象.xxx |
| 例子 | Math.max()、Integer.parseInt() |
player.getName() |
static 方法里不能直接用实例成员
static void test() {
name = "x"; // ❌ 编译错误:name 是实例成员
}
@Mod 主类、注册方法经常是 static。
7.7 实战:模组场景¶
// 简化版:自定义武器类(真实模组里是继承 Item)
public class Weapon {
private final String id; // final:创建后不可改
private final int damage;
private int durability;
public Weapon(String id, int damage, int durability) {
this.id = id;
this.damage = damage;
this.durability = durability;
}
public String getId() { return id; }
public int getDamage() { return damage; }
public int getDurability() { return durability; }
public boolean use() {
durability--;
return durability <= 0; // 返回是否损坏
}
}
// 使用
Weapon sword = new Weapon("ffs_steel_sword", 8, 250);
boolean broken = sword.use();
7.8 小练习¶
- 设计一个
Dog类:属性 name、age;方法bark();构造器初始化 - 给 Dog 加 private 封装 + getter/setter,setAge 里校验不能为负
- 设计一个
Counter类:static 属性 count,static 方法 increment(),每次调用 +1,验证多个"对象"共享同一个 count - 写一个
Rectangle类:长宽属性,方法area()和perimeter()
本章小结¶
- 类 = 属性 + 方法;对象 = new 出来的实例
- 构造器初始化对象,this 指当前对象
- 封装:private 属性 + getter/setter
- static 属于类,用类名访问
- final 字段创建后不可变(模组里注册名常用)
下一章:08 继承与多态