构造器
成员方法 也叫实列域
private String name; private double salary; private LocalDate hireDay;
构造器与类同名。 在构造 某个类的对象时,
构造器会运行, 以便将实例域 (成员方法 )初始化为所希望的状态。
、
例如, 当使用下面这条代码创建 Employee 类实例时: new Eraployee("]ames Bond", 100000, 1950, 1, 1)
将会把实例域设置为:
name = "James Bond";
salary = 100000;
hireDay = LocalDate.of(1950, 1, 1); // January 1, 1950
构造器与其他的方法有一个重要的不同
造器总是伴随着 new 操作符的执行被调用,
而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。 例如,
janes.EmployeeCJames Bond", 250000, 1950, 1, 1) // ERROR
构造器与类同名 •每个类可以有一个以上的构造器 •构造器可以有 0 个、
1 个或多个参数 •构造器没有返回值 •构造器总是伴随着 new
Java 构造器的工作方式与 C++ —样。但是, 要记住所有的 Java 对象都是在
一起使用 C++ 程序员最易犯的错误就是忘 堆中构造的, 构造器总是伴随着 new 操作符 。
记 new 操作符:
Employee number007("]anie5 Bond", 100000, 1950, 1, 1);
请注意,不要在构造器中定义与实例域重名的局部变量。
方法用于操作对象以及存取它们的实例域。
封装的优点
最后, 再仔细地看一下非常简单的 getName 方法、 getSalary 方法和 getHireDay 方法。
public String getName()
public double getSalaryO
{
return salary;
}
public LocalDate getHireDay()
{
return hireDay;
}
这些都是典型的访问器方法。由于它们只返回实例域值, 因此又称为域访问器。
在有些时候, 需要获得或设置实例域的值。 因此, 应该提供下面三项内容: •一 私有的数据域;
一 公有的域访问器方法; •一个公有的域更改器方法。
这样做要比提供一个简单的公有数据域复杂些, 但是却有着下列明显的好处:
首先, 可以改变内部实现, 除了该类的方法之外, 不会影响其他代码。 例如, 如果将存 储名字的域改为:
String firstName; String lastName;
那么 getName 方法可以改为返回
firstName + " " + 1astName
注意不要编写返回引用可变对象的访问器方法
在 Employee 类中就违反了这个设 计原则, 其中的 getHireDay 方法返回了一个 Date 类对象:
class Employee
{
{
LocalDate 类没有更改器方法, 与之不同, Date 类有一个更改器方法 setTime, 可以 在 这 里 设 置 毫 秒 数。
Date 对象是可变的, 这一点就破坏了封装性! 请看下面这段代码:
Employee harry = . .
Date d = harry.getHi reDayO ;
double tenYearsInMilliSeconds = 10 * 365.25 * 24 * 60 * 60 * 1000; d.setTime(d.getTime() -(long) tenYearsInMilliSeconds);
// let's give Harry ten years of added seniority
出错的原因很微妙。 d 和 harry.hireDay 引用同一个对象(请参见图 4-5 )。 对 d 调用 更改器方法就可以自动地改变这个雇员对象的私有状态!
Employee
salary
hireDay =
「冬14-5 返回可变数据域的引用
如果需要返回一个可变对象的引用, 应该首先对它进行克隆(clone)。 对象 clone 是 指存放在另一个位置上的对象副本。 有关对象 clone 的详细内容将在第 6 章中讨论。 下 面是修改后的代码:
private Date hireDay;
public Date getHireDayO
return hireDay; // Bad
Date 对象是可变的, 这一点就破坏了封装性!
LocalDate 类没有更改器方法, 与之不同, Date 类有一个更改器方法 setTime, 可以 在 这 里 设 置 毫 秒 数
Employee harry = . .
Date d = harry.getHi reDayO ;
double tenYearsInMilliSeconds = 10 * 365.25 * 24 * 60 * 60 * 1000; d.setTime(d.getTime() -(long) tenYearsInMilliSeconds);
// let's give Harry ten years of added seniority
出错的原因很微妙。 d 和 harry.hireDay 引用同一个对象(请参见图 4-5 )。 对 d 调用 更改器方法就可以自动地改变这个雇员对象的私有状态!
如果需要返回一个可变对象的引用, 应该首先对它进行克隆(clone)。 对象 clone 是 指存放在另一个位置上的对象副本。
eturn (Date) hireDay.clone(); // O