封装的好处--笔记

以下笔记摘自《java核心技术卷1》

 

以下给出了一个薪金管理系统的一部分代码

package Employee;

import java.time.LocalDate;

public class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;
    public Employee(String name, double salary, int year,int month,int day) {
        this.name = name;
        this.salary = salary;
        this.hireDay = LocalDate.of(year,month,day);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public LocalDate getHireDay() {
        return hireDay;
    }

    public void setHireDay(LocalDate hireDay) {
        this.hireDay = hireDay;
    }
    public void raiseSalary(double byPercent) {
        double raise=salary*byPercent/100;
        salary+=raise;
    }
}

package Employee;

public class EmployeeTest {
    public static void main(String[] args) {
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("Carl",75000,1987,12,15);
        staff[1]=new Employee("Harry",50000,1989,10,1);
        staff[2]=new Employee("Tony",40000,1990,3,15);
        for(Employee e : staff)
            e.raiseSalary(5);
        for(Employee e : staff)
            System.out.println("name="+e.getName()+",salary="+e.getSalary()+",hireDay="+e.getHireDay());
    }
}

 封装的优点

关键字private确保只有Employee类自身的方法能够访问这些实例域,而其它类的方法不能够读写这些域。

public String getName() {
    return name;
}

是典型的访问器方法。

将name、salary和hireDay域标记为public,以此来取代独立的访问器方法会不会更容易些呢?

name是一个只读域。一旦在构造器中设置完毕,就没有任何一个办法可以对他进行修改,这样来确保name域不会受到外界的破坏。

虽然salary不是只读域,但是它只能用raiseSalary方法进行修改,一旦这个域值出现了错误,只要调试这个方法就可以了。如果salary域是public的,破坏这个域值的捣乱者有可能会出现在任何地方,

有些时候,需要获得或设置实例域的值,应提供以下三种内容:

  • 一个私有的数据域
  • 一个共有的域访问器方法
  • 一个公有的域更改器方法

这样做要比提供一个简单的共有数据域复杂些,但是却有着下列明显的好处:

1、首先,可以改变内部实现,除了该类的方法之外,不会影响其他代码。

     例如:如果将存储名字的域改为:

     String firstName;

     String lastName; 

     那么,getName方法可以改为返回

     fisrtName+""+lastName

    对于这点改变,程序的其他部分完全不可见。

2、为了进行新旧数据表示之间的转换,访问其方法和更改器方法有可能需要做许多工作。但是,浙江为我们带来了第二点好处:更改器方法可以执行错误检查,然而直接对域进行赋值将不会进行这些处理。例如setSalary方法可以检查新近是否小于0。

注意:不要编写“返回可变引用对象”的访问器方法!

现在假如把Employ类中的

private LocalDate hireDay;部分改为private Date hireDay;就会出问题。

LocalDate类没有更改器方法,与之不同,Date类有一个更改器方法setTime,可以在这里设置毫秒数。

Date对象是可变的,这一点就破坏了封装性。

假如有人写

Employee harry=...;
Date d=harry.getHireDay();
double tenYearsInMilliSeconds=10*365.25*24*60*60*1000;
d.setTime(d.getTime()-(long)tenYearsInMilliSeconds);

那么,d和harry.hireDay引用同一个对象,对d调用更改器方法可以自动的改变这个雇员对象的私有状态。

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值