跳转至

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 是实例成员
}
因为 static 方法不依附于对象,不知道用哪个对象的 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 小练习

  1. 设计一个 Dog 类:属性 name、age;方法 bark();构造器初始化
  2. 给 Dog 加 private 封装 + getter/setter,setAge 里校验不能为负
  3. 设计一个 Counter 类:static 属性 count,static 方法 increment(),每次调用 +1,验证多个"对象"共享同一个 count
  4. 写一个 Rectangle 类:长宽属性,方法 area() 和 perimeter()

本章小结

  • 类 = 属性 + 方法;对象 = new 出来的实例
  • 构造器初始化对象,this 指当前对象
  • 封装:private 属性 + getter/setter
  • static 属于类,用类名访问
  • final 字段创建后不可变(模组里注册名常用)

下一章:08 继承与多态

🏠 返回总站