在前三天的学习中,我们掌握了 Java 的基础语法、数组和方法的使用。从今天开始,我们将进入 Java 编程的核心思想 ——面向对象编程(OOP)。面向对象是 Java 区别于其他语言(如 C 语言)的重要特性,也是理解 JavaWeb 框架设计的基础。今天我们先学习面向对象的两个核心概念:类与对象,以及封装特性。


从面向过程到面向对象

编程思想的转变
  • ​面向过程​​:关注 "怎么做",将问题拆解为步骤,通过函数实现每一步并依次调用。例如,实现 "登录功能" 时,会拆解为 "接收输入→验证账号→验证密码→跳转页面" 等步骤。
  • ​面向对象​​:关注 "谁来做",将问题抽象为对象,通过对象之间的交互完成功能。例如,"登录功能" 中会有 "用户对象"(负责存储账号密码)和 "验证对象"(负责验证逻辑)。

面向对象的优势在于代码复用性高、扩展性强,尤其适合复杂项目开发(如 JavaWeb 系统)。


类与对象的概念

什么是类?

类(Class)是抽象的模板,用于描述一类事物的共同属性和行为。例如:

  • "学生类" 包含属性(姓名、年龄、学号)和行为(上课、考试)。
  • "汽车类" 包含属性(颜色、排量)和行为(启动、加速)。
什么是对象?

对象(Object)是类的具体实例。例如:

  • "张三(20 岁,学号 2023001)" 是 "学生类" 的一个对象。
  • "一辆红色 2.0T 的特斯拉" 是 "汽车类" 的一个对象。

​类与对象的关系​​:类是对象的模板,对象是类的实例化结果。


类的定义与对象的创建

定义类的语法
// 类的定义格式
修饰符 class 类名 {
    // 属性(成员变量)
    数据类型 属性名1;
    数据类型 属性名2;
    
    // 行为(成员方法)
    修饰符 返回值类型 方法名(参数列表) {
        // 方法体
    }
}

​注意​​:

  • 类名使用大驼峰命名法(每个单词首字母大写,如 StudentUserInfo)。
  • 成员变量定义在类中,方法之外,有默认初始值(如 int 默认 0String 默认 null)。
实例:定义一个 Student
// 学生类
public class Student {
    // 属性(成员变量)
    String name; // 姓名
    int age; // 年龄
    String studentId; // 学号
    
    // 行为(成员方法)
    // 上课方法
    public void attendClass() {
        System.out.println(name + "正在上课");
    }
    
    // 考试方法
    public void takeExam() {
        System.out.println(name + "正在参加考试");
    }
}

创建对象与使用

通过 new 关键字创建对象,格式为:

类名 对象名 = new 类名();

使用对象的属性和方法:

public class TestStudent {
    public static void main(String[] args) {
        // 创建Student类的对象
        Student stu1 = new Student();
        
        // 给对象的属性赋值
        stu1.name = "张三";
        stu1.age = 20;
        stu1.studentId = "2023001";
        
        // 调用对象的方法
        stu1.attendClass(); // 输出:张三正在上课
        stu1.takeExam(); // 输出:张三正在参加考试
        
        // 创建第二个对象
        Student stu2 = new Student();
        stu2.name = "李四";
        stu2.attendClass(); // 输出:李四正在上课
    }
}

构造方法:初始化对象

创建对象时,new 后面的 类名() 其实在调用构造方法。构造方法用于对象的初始化(如给属性赋初始值)。

构造方法的特点
  • 方法名与类名完全相同。
  • 没有返回值类型(连 void 都不写)。
  • 若未手动定义构造方法,系统会自动生成默认无参构造方法。
定义构造方法
public class Student {
    String name;
    int age;
    String studentId;
    
    // 无参构造方法(手动定义)
    public Student() {
        // 初始化代码
        System.out.println("创建了一个学生对象");
    }
    
    // 有参构造方法(带参数)
    public Student(String n, int a, String id) {
        name = n; // 给name赋值
        age = a; // 给age赋值
        studentId = id; // 给studentId赋值
    }
    
    // 成员方法
    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",学号:" + studentId);
    }
}
使用构造方法创建对象
public class TestConstructor {
    public static void main(String[] args) {
        // 调用无参构造
        Student stu3 = new Student(); // 输出:创建了一个学生对象
        stu3.name = "王五";
        stu3.age = 21;
        stu3.showInfo(); // 输出:姓名:王五,年龄:21,学号:null
        
        // 调用有参构造(直接初始化属性)
        Student stu4 = new Student("赵六", 19, "2023002");
        stu4.showInfo(); // 输出:姓名:赵六,年龄:19,学号:2023002
    }
}

​注意​​:若手动定义了构造方法,系统将不再生成默认无参构造,建议手动添加无参构造。


封装:面向对象的核心特性

什么是封装?

封装(Encapsulation)指隐藏对象的属性和实现细节,仅通过公共方法暴露接口。目的是保护数据安全性,防止外部随意修改。
例如:手机的内部电路是隐藏的(属性私有),用户通过按键(公共方法)操作手机。

封装的实现步骤
  1. 将成员变量用 private 修饰(私有,仅本类可访问)。
  2. 提供 publicgetter 方法(获取属性值)和 setter 方法(修改属性值)。
实例:封装 Student
public class Student {
    // 1. 私有属性
    private String name; // 私有,外部无法直接访问
    private int age;
    
    // 2. 无参构造
    public Student() {}
    
    // 3. getter和setter方法
    // 获取name
    public String getName() {
        return name;
    }
    
    // 设置name
    public void setName(String n) {
        // 可以添加验证逻辑
        if (n.length() > 0) {
            name = n;
        } else {
            System.out.println("姓名不能为空");
        }
    }
    
    // 获取age
    public int getAge() {
        return age;
    }
    
    // 设置age
    public void setAge(int a) {
        // 验证年龄合法性
        if (a >= 0 && a <= 120) {
            age = a;
        } else {
            System.out.println("年龄不合法");
        }
    }
    
    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}
使用封装后的类
public class TestEncapsulation {
    public static void main(String[] args) {
        Student stu = new Student();
        
        // 错误:无法直接访问私有属性
        // stu.name = "张三"; 
        
        // 正确:通过setter设置值
        stu.setName("张三");
        stu.setAge(20);
        stu.showInfo(); // 输出:姓名:张三,年龄:20
        
        // 测试验证逻辑
        stu.setName(""); // 输出:姓名不能为空
        stu.setAge(150); // 输出:年龄不合法
        stu.showInfo(); // 输出:姓名:张三,年龄:20(值未改变)
        
        // 通过getter获取值
        System.out.println("获取姓名:" + stu.getName()); // 输出:获取姓名:张三
    }
}

总结与实践

知识点回顾

今天我们学习了面向对象的基础:

  • 类是抽象模板(属性 + 方法),对象是类的具体实例。
  • 构造方法用于初始化对象,分为无参和有参两种。
  • 封装通过 private 修饰属性,getter/setter 暴露接口,保护数据安全。
实践任务

定义一个 User 类:

  • 属性:username(用户名,String)、password(密码,String)、email(邮箱,String),均用 private 修饰。
  • 提供无参构造和全参构造。
  • 生成所有属性的 gettersetter 方法,其中 setPassword 需验证密码长度≥6,否则提示 "密码太短"。
  • 定义 login() 方法:输出 "用户名:xxx 登录成功"。

测试类 TestUser

  • 创建两个 User 对象(分别用无参和有参构造)。
  • 调用 setter 方法修改属性,测试密码验证逻辑。
  • 调用 login() 方法。
参考答案

User类实现

public class User {
    // 私有属性(封装)
    private String username; // 用户名
    private String password; // 密码
    private String email;    // 邮箱

    // 无参构造方法(必须显式定义,否则无法通过无参方式创建对象)
    public User() {}

    // 全参构造方法(初始化所有属性)
    public User(String username, String password, String email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }

    // getter 和 setter 方法(暴露公共接口)
    // username 的 getter/setter
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    // password 的 getter/setter(带验证逻辑)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        // 验证密码长度≥6
        if (password != null && password.length() >= 6) {
            this.password = password;
        } else {
            System.out.println("密码太短(需≥6位)");
        }
    }

    // email 的 getter/setter
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    // login 方法(输出登录信息)
    public void login() {
        System.out.println("用户名:" + username + " 登录成功");
    }
}

TestUser 测试类实现​

public class TestUser {
    public static void main(String[] args) {
        // 任务1:使用无参构造创建 User 对象,并通过 setter 修改属性
        User user1 = new User();
        user1.setUsername("zhangsan");    // 设置用户名
        user1.setPassword("12345");       // 尝试设置短密码(触发验证)
        user1.setEmail("zhangsan@test.com");// 设置邮箱
        user1.login();                      // 调用登录方法(输出:用户名:zhangsan 登录成功)

        // 任务2:使用全参构造创建 User 对象,并测试密码验证逻辑
        User user2 = new User("lisi", "678901", "lisi@test.com");
        user2.login();                      // 调用登录方法(输出:用户名:lisi 登录成功)

        // 测试密码修改(合法长度)
        user2.setPassword("new666");        // 密码长度6,设置成功
        user2.login();                      // 输出:用户名:lisi 登录成功

        // 测试密码修改(非法长度)
        user2.setPassword("abc");           // 密码长度3,触发验证提示
        user2.login();                      // 输出:用户名:lisi 登录成功(密码未改变)
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐