java

面向对象基础:类、对象与封装

By AI-Writer 10 min read

面向对象基础:类、对象与封装

面向对象编程(OOP,Object-Oriented Programming)是 Java 的核心编程范式。Java 的一切皆为对象——从字符串到数组,从线程到网络连接,全部以对象的形式存在。理解类与对象的概念,是掌握 Java 的必经之路。本文将深入讲解类的定义、对象的创建、构造器以及封装这一 OOP 基础特性。

类与对象的概念

**类(Class)**是对一类事物的抽象描述,是一个模板或蓝图;**对象(Object)**是类的具体实例,是真实存在的实体。

plaintext
类:汽车设计图纸
对象:一辆具体的特斯拉 Model 3

在 Java 中,先有类,才能创建对象:

java
// 定义一个 "学生" 类
public class Student {
    // ============ 成员变量(属性)===========
    String name;    // 姓名
    int    age;     // 年龄
    String studentId;  // 学号

    // ============ 构造器(Constructor)===========
    // 无参构造器
    public Student() {
    }

    // 有参构造器
    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }

    // ============ 成员方法(行为)===========
    void study() {
        System.out.println(name + " 正在学习...");
    }

    void introduce() {
        System.out.println("我叫 " + name + ",今年 " + age + " 岁,学号是 " + studentId);
    }
}
java
// 创建对象(实例化)
Student alice = new Student("Alice", 20, "S2024001");
alice.introduce();
// 我叫 Alice,今年 20 岁,学号是 S2024001

alice.study();
// Alice 正在学习...

// 再创建一个独立的对象
Student bob = new Student("Bob", 22, "S2024002");
bob.introduce();
// 我叫 Bob,今年 22 岁,学号是 S2024002

关键点:每个对象都是独立的实例,拥有自己的属性值。修改 alicename 不会影响 bob

成员变量与成员方法

成员变量

成员变量(Field)定义在类内部、方法外部,描述对象的状态

java
public class Rectangle {
    // 成员变量(实例变量),每个对象独立一份
    double width;
    double height;

    // 静态变量(类变量),所有对象共享一份
    static int instanceCount = 0;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
        instanceCount++;  // 每创建一个实例,计数器加一
    }

    double area() {
        return width * height;
    }

    double perimeter() {
        return 2 * (width + height);
    }
}
java
Rectangle r1 = new Rectangle(3.0, 4.0);
Rectangle r2 = new Rectangle(5.0, 6.0);

System.out.println(r1.area());    // 12.0
System.out.println(r2.area());    // 30.0

// 静态变量通过类名访问
System.out.println(Rectangle.instanceCount);  // 2

成员方法

成员方法定义在类内部,描述对象的行为

java
public class Counter {
    private int count = 0;  // 私有变量,外部无法直接访问

    // 递增
    public void increment() {
        count++;
    }

    // 递减
    public void decrement() {
        count--;
    }

    // 获取当前值
    public int getCount() {
        return count;
    }

    // 重置
    public void reset() {
        count = 0;
    }
}

构造器

构造器是创建对象时自动调用的特殊方法,用于初始化对象的状态。

无参构造器

如果类中没有显式定义任何构造器,Java 编译器会自动生成一个无参构造器(默认构造器):

java
public class Dog {
    String name;

    // 如果不写构造器,Java 会自动生成:
    // public Dog() {}
}

// 使用无参构造器创建对象
Dog dog = new Dog();
dog.name = "旺财";

有参构造器(推荐)

java
public class Dog {
    String name;
    String breed;
    int age;

    // 有参构造器:创建时直接初始化
    public Dog(String name, String breed, int age) {
        this.name = name;
        this.breed = breed;
        this.age = age;
    }

    void bark() {
        System.out.println(name + " 汪汪叫!");
    }

    void info() {
        System.out.println(name + " 是一只 " + age + " 岁的 " + breed + "。");
    }
}
java
Dog myDog = new Dog("旺财", "金毛", 3);
myDog.bark();   // 旺财 汪汪叫!
myDog.info();   // 旺财 是一只 3 岁的金毛。

构造器重载

同方法一样,构造器也支持重载——定义多个参数列表不同的构造器:

java
public class User {
    String username;
    String email;
    int age;

    // 构造器重载
    public User() {
        // 默认值
        this.username = "匿名";
        this.email = "unknown@example.com";
        this.age = 0;
    }

    public User(String username, String email) {
        this.username = username;
        this.email = email;
        this.age = 18;  // 默认年龄
    }

    public User(String username, String email, int age) {
        this.username = username;
        this.email = email;
        this.age = age;
    }
}

this 关键字

this 指向当前对象,用于区分成员变量和局部变量(同名时必须用 this):

java
public class Point {
    int x;
    int y;

    public Point(int x, int y) {
        // this.x 表示当前对象的成员变量 x
        // x 表示参数中的局部变量 x
        this.x = x;
        this.y = y;
    }

    // this 还可以调用同类中的其他构造器(必须在构造器第一行)
    public Point() {
        this(0, 0);  // 调用另一个构造器 Point(int, int)
    }

    void move(int dx, int dy) {
        this.x += dx;
        this.y += dy;
    }
}

访问修饰符与封装

**封装(Encapsulation)**是 OOP 的三大特性之一(另外两个是继承和多态),指的是将数据和操作数据的代码组织在一起,对外隐藏实现细节,仅暴露必要的接口。

访问修饰符

Java 提供四个层级的访问控制:

修饰符同一类内同一包内子类(不同包)任意位置
private
default(无修饰符)
protected
public
java
public class Person {
    public    String name;     // 公开:任何地方都能访问
    protected int    age;      // 受保护:子类和同包可访问
    private   String idCard;    // 私有:仅本类内部可访问
              String address;   // 默认(包私有):同包内可访问
}

实现封装:getter / setter

将成员变量设为 private,通过 public 方法访问,这就是最常见的封装模式:

java
public class BankAccount {
    // 私有化属性,外部无法直接访问
    private String accountNumber;
    private double balance;

    // 构造器
    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    // Getter(读取)
    public String getAccountNumber() {
        return accountNumber;
    }

    public double getBalance() {
        return balance;
    }

    // Setter(写入),可加入业务校验逻辑
    public void deposit(double amount) {
        if (amount <= 0) {
            System.out.println("存款金额必须为正数");
            return;
        }
        this.balance += amount;
        System.out.println("存款成功,当前余额:" + this.balance);
    }

    public void withdraw(double amount) {
        if (amount <= 0) {
            System.out.println("取款金额必须为正数");
            return;
        }
        if (amount > this.balance) {
            System.out.println("余额不足!");
            return;
        }
        this.balance -= amount;
        System.out.println("取款成功,当前余额:" + this.balance);
    }
}
java
BankAccount account = new BankAccount("6222021234567890", 1000.0);

// 无法直接访问私有属性
// account.balance = 1000000;  // 编译错误!

account.deposit(500);   // 存款成功,当前余额:1500.0
account.withdraw(300); // 取款成功,当前余额:1200.0

System.out.println("账户:" + account.getAccountNumber());
System.out.println("余额:" + account.getBalance());

封装的好处:1)保护数据不被非法值破坏;2)隐藏内部实现,外部只依赖接口;3)便于后期维护和修改内部逻辑而不影响调用方。

Lombok 简化 getter/setter(可选)

在实际项目中,手写 getter/setter 繁琐,通常使用 Lombok 注解自动生成:

java
import lombok.Getter;
import lombok.Setter;

public class Product {
    @Getter @Setter
    private String name;

    @Getter @Setter
    private double price;

    @Getter @Setter
    private int stock;
}

// 编译后 Lombok 会自动生成 getName()、setName()、getPrice() 等方法

完整示例:自定义数组容器

让我们用一个完整的示例串联所有知识点:

java
public class IntList {
    private int[] data;    // 内部数组
    private int size;       // 当前元素个数

    // 构造器:初始容量为 10
    public IntList() {
        this.data = new int[10];
        this.size = 0;
    }

    // 添加元素
    public void add(int value) {
        if (size >= data.length) {
            resize();  // 容量翻倍
        }
        data[size++] = value;
    }

    // 获取指定位置元素
    public int get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界: " + index);
        }
        return data[index];
    }

    // 获取当前元素个数
    public int size() {
        return size;
    }

    // 扩容方法(内部使用)
    private void resize() {
        int[] newData = new int[data.length * 2];
        System.arraycopy(data, 0, newData, 0, size);
        data = newData;
    }

    // 打印所有元素
    public void printAll() {
        System.out.print("[ ");
        for (int i = 0; i < size; i++) {
            System.out.print(data[i]);
            if (i < size - 1) System.out.print(", ");
        }
        System.out.println(" ]");
    }
}
java
IntList list = new IntList();
list.add(10);
list.add(20);
list.add(30);
list.printAll();  // [ 10, 20, 30 ]

System.out.println("大小:" + list.size());  // 大小:3
System.out.println("第1个元素:" + list.get(0));  // 第1个元素:10

小结

  • 是模板,对象是类的实例;使用 new 关键字创建对象
  • 成员变量描述对象状态,成员方法描述对象行为;static 变量为类变量,所有实例共享
  • 构造器用于初始化对象,支持重载;this 关键字解决成员变量与参数同名冲突
  • 封装通过 private 隐藏数据,public 方法(getter/setter)提供受控访问
  • private 最常用——除非明确需要外部访问,不要将成员变量设为 public

掌握类与对象后,下一节我们将学习面向对象的核心特性——继承、多态与接口,这是 Java 实现代码复用和多态行为的关键机制。

#java #面向对象 #类 #对象 #封装 #构造器

评论

A

Written by

AI-Writer

Related Articles

java
#7

集合框架与 Stream API

系统讲解 Java 三大集合体系(List/Set/Map)、核心实现类、Stream API 筛选映射归约操作、Lambda 表达式与方法引用

Read More
java
#8

JDBC 与数据库交互

详解 JDBC 编程五步曲:加载驱动、建立连接、执行 SQL、处理结果集,以及 PreparedStatement 防注入、事务控制和连接池原理

Read More