跟der包学习java_day7「封装(Encapsulation)」

内容分享2周前发布
0 0 0

今日目标

理解封装的意义和作用掌握访问修饰符(public、private、protected、默认)的用法学会用
private
隐藏属性,用
getter/setter
方法提供访问接口理解
this
关键字的作用

一、为什么需要封装?

先看一个没有封装的例子:



public class Person {
    String name;
    int age; // 年龄是公开的,外部可以直接修改
}
 
// 测试类
public class TestPerson {
    public static void main(String[] args) {
        Person p = new Person();
        p.age = -20; // 年龄被设置为负数,这在现实中是不合理的!
        System.out.println("年龄:" + p.age); // 输出:-20
    }
}

问题在于:外部可以直接修改
age
属性,甚至设置不合理的值(如负数),导致数据不安全。

封装的解决思路

将属性隐藏起来(不让外部直接访问)。提供公共方法,控制对属性的访问(比如设置年龄时检查合法性)。

二、访问修饰符:控制访问权限

Java 通过访问修饰符来控制类、属性、方法的访问范围,共有 4 种:

修饰符 同一类中 同一包中 不同包的子类 不同包的非子类 常见用途

private
✔️ 隐藏类的属性或内部方法

默认
(不写)
✔️ ✔️ 同包内可见的工具类 / 方法

protected
✔️ ✔️ ✔️ 允许子类访问的属性 / 方法

public
✔️ ✔️ ✔️ ✔️ 对外暴露的接口(类 / 方法)

核心原则:属性通常用
private
隐藏,方法根据需要用
public
(对外暴露)或
private
(内部使用)。

三、封装的实现:
private
 + 
getter/setter

1. 用
private
修饰属性(隐藏数据)


public class Person {
    private String name; // 私有属性,外部不能直接访问
    private int age;     // 私有属性
}

此时,外部直接访问
p.age
会报错(编译不通过),达到了隐藏数据的目的。

2. 提供
public

getter

setter
方法(控制访问)


getter
:获取属性值(命名格式:
public 数据类型 get属性名()
)。
setter
:设置属性值(命名格式:
public void set属性名(参数)
),可以在方法中添加数据校验。

示例:完善 Person 类



public class Person {
    private String name;
    private int age;
    
    // name的getter:获取姓名
    public String getName() {
        return name;
    }
    
    // name的setter:设置姓名
    public void setName(String n) {
        name = n; // 简单赋值(也可添加校验,如非空判断)
    }
    
    // age的getter:获取年龄
    public int getAge() {
        return age;
    }
    
    // age的setter:设置年龄(添加合法性校验)
    public void setAge(int a) {
        if (a < 0 || a > 150) { // 年龄不能小于0或大于150
            System.out.println("年龄不合法!默认设置为18");
            age = 18; // 赋默认值
        } else {
            age = a; // 合法则赋值
        }
    }
}
3. 外部通过
getter/setter
访问属性


public class TestPerson {
    public static void main(String[] args) {
        Person p = new Person();
        
        // 不能直接访问私有属性(编译报错)
        // p.age = 20; 
        
        // 通过setter设置属性
        p.setName("张三");
        p.setAge(-20); // 年龄不合法!默认设置为18
        
        // 通过getter获取属性
        System.out.println("姓名:" + p.getName()); // 张三
        System.out.println("年龄:" + p.getAge());  // 18
    }
}

跟der包学习java_day7「封装(Encapsulation)」

封装的好处

数据安全:通过
setter
控制属性的赋值,避免不合理数据。灵活性:如果后期需要修改校验规则(如年龄上限改为 120),只需修改
setter
方法,外部调用者无需改动。隐藏实现细节:外部只需要知道 “如何用”(调用方法),不需要知道 “内部如何实现”。

四、
this
关键字

当方法的参数名与类的属性名相同时,会出现 “命名冲突”,此时用
this
关键字区分属性参数


this
代表当前对象(调用该方法的对象)。

示例:用
this
解决命名冲突


public class Person {
    private String name;
    private int age;
    
    // 参数名与属性名相同(name、age)
    public void setName(String name) {
        // this.name 指当前对象的属性name
        // 后面的name 指方法的参数name
        this.name = name; 
    }
    
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            this.age = 18; // this.age 指属性age
        } else {
            this.age = age;
        }
    }
    
    // 构造方法中也可以用this
    public Person(String name, int age) {
        this.name = name; // 区分属性和参数
        this.age = age;
    }
}
示例:

Person.java



package study_7_2;
 
public class Person {
 
    private String name;
    private int age;
 
    public void setName(String name){
        this.name = name;
    }
 
    public void setAge(int age){
        this.age = age;
    }
 
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
 
    public String getName(){
        return name;
    }
 
    public int age(){
        return age;
    }
 
 
}

testPerson.java



package study_7_2;
 
public class testPerson {
 
    public static void main(String[] args){
        Person p1 = new Person("张三",18);
 
        System.out.println(p1.getName());
        System.out.println(p1.age());
 
    }
 
}

跟der包学习java_day7「封装(Encapsulation)」


this
的其他用法:

调用本类的其他构造方法(
this(参数)
,必须放在构造方法的第一行):



public class Person {
    private String name;
    private int age;
    
    // 无参构造
    public Person() {
        this("默认姓名", 18); // 调用有参构造,简化代码
    }
    
    // 有参构造
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
一、构造方法的作用

构造方法用于创建对象时初始化对象的属性,是 Java 中创建对象的 “专属方法”。

无参构造(
public Person()

当创建对象时不传递任何参数时,会调用这个构造方法。它内部通过 
this("默认姓名", 18)
 调用了有参构造,目的是复用有参构造的逻辑,给对象设置默认的姓名和年龄(“默认姓名”、18)。

有参构造(
public Person(String name, int age)

当创建对象时传递姓名和年龄参数时,会调用这个构造方法,直接给对象的 
name
 和 
age
 属性赋值,实现自定义初始化

Person.java



package study_7_3;
 
public class Person {
    private String name;
    private int age;
 
 
    public Person(){
        this("默认姓名", 18);
    }
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName(){
        return name;
    }
 
    public int getAge(){
        return age;
    }
 
}

TestPerson.java



package study_7_3;
 
public class TestPerson {
 
    public static void main(String[] args){
 
        Person p1 = new Person();
 
        System.out.println(p1.getName());
        System.out.println(p1.getAge());
    }
 
}

跟der包学习java_day7「封装(Encapsulation)」

五、完整示例:封装的实践

Student.java



// 学生类(封装属性,提供getter/setter)
public class Student {
    // 私有属性
    private String id;    // 学号
    private String name;  // 姓名
    private double score; // 成绩(0-100)
    
    // 无参构造
    public Student() {}
    
    // 有参构造
    public Student(String id, String name, double score) {
        this.id = id;
        this.name = name;
        this.setScore(score); // 调用setter,复用校验逻辑
    }
    
    // getter和setter
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public double getScore() {
        return score;
    }
    
    public void setScore(double score) {
        // 成绩校验:必须在0-100之间
        if (score < 0 || score > 100) {
            System.out.println("成绩不合法!默认设置为0");
            this.score = 0;
        } else {
            this.score = score;
        }
    }
    
    // 打印学生信息
    public void showInfo() {
        System.out.println("学号:" + id + ",姓名:" + name + ",成绩:" + score);
    }
}
 
// 测试类
public class TestStudent {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.setId("S001");
        stu1.setName("张三");
        stu1.setScore(95);
        stu1.showInfo(); // 学号:S001,姓名:张三,成绩:95.0
        
        Student stu2 = new Student("S002", "李四", 150); // 成绩不合法!默认设置为0
        stu2.showInfo(); // 学号:S002,姓名:李四,成绩:0.0
    }
}

TestStudent.java



package study_7_4;
 
public class TestStudent {
 
    public static void main(String[] args){
        Student stu1 = new Student();
        stu1.setId("S001");
        stu1.setName("张三");
        stu1.setScore(95);
        stu1.showInfo();
 
        Student stu2 = new Student("S002","李四",100);
        stu2.showInfo();
    }
}

跟der包学习java_day7「封装(Encapsulation)」

六、练习

封装练习:定义一个 “图书类(Book)”,包含属性
bookId
(图书编号)、
title
(书名)、
price
(价格,必须≥0)。用
private
修饰属性,提供
getter/setter

setPrice
需校验价格≥0,否则默认 0),并添加构造方法和
showInfo
方法(打印图书信息)。

this 练习:在上面的 Book 类中,确保构造方法和
setter
中使用
this
关键字区分属性和参数。

今日总结

封装的核心是 “隐藏内部细节,暴露公共接口”,通过
private
隐藏属性,
getter/setter
控制访问。访问修饰符控制访问范围:
private
(仅本类)、默认(同包)、
protected
(同包 + 子类)、
public
(全局)。
this
关键字
代表当前对象,用于区分属性和参数,或调用本类其他构造方法。

其他:

Java 中构造方法的两种赋值逻辑:this 直接赋值与 setter 方法调用的区别与应用场景-CSDN博客

跟der包学习java_day7「封装(Encapsulation)」

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...