在此记录一个之前从未了解到的问题。
首先来看本人定义的一个ADT,命名为Employee,定义的ADT如下:
public class Employee {
private final String name;
private final String job;
private final String phone;
// Abstraction function:
// name映射为员工名字,job映射为员工职务,phone映射为员工电话号码
// Representation invariant:
// name,job,phone都不为空
// Safety from rep exposure:
// 使用private final修饰实例字段,防御式编程。
/**
* 初始化
* @param name 员工名字
* @param job 员工职务
* @param phone 员工电话号码
*/
public Employee(String name,String job,String phone) {
this.name=name;
this.job=job;
this.phone=phone;
checkrep();
}
/**
* 获得员工名字
* @return 员工名字
*/
public String getname() {
return name;
}
/**
* 获得员工职务
* @return 员工职务
*/
public String getjob() {
return job;
}
/**
* 获得员工电话号码
* @return 员工电话号码
*/
public String getphone() {
return phone;
}
/**
* 检查
*/
private void checkrep() {
assert name!=null;
assert job!=null;
assert phone!=null;
}
@Override
public String toString() {
String s="Employee:\n"+"姓名:"+name+"\n"+"职务:"+job+"\n"+"手机号码:"+phone+"\n"+"\n";
return s;
}
@Override
public boolean equals(Object obj) {
if(obj==null) {
return false;
}
if(obj instanceof Employee) {
if(this==obj) {
return true;
}
Employee e=(Employee) obj;
if(name.equals(e.name)&&job.equals(e.job)&&phone.equals(e.phone)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return name.hashCode()+job.hashCode()+phone.hashCode();
}
}
其中,name、job、phone均为private final修饰的,而在重写equals的过程中,我们发现在将obj强制类型转换为Employee后,在判断两个对象的name、job和phone是否相同的过程中可以直接访问e中的name、job和phone,即可以直接使用e.name、e.job、e.phone,而name、job、phone这三个表示都是private final的,按常规认识来说应当无法直接访问到,所以这是一个非常有意思的地方。
在翻阅PPT后,我们又发现了一处出现这种情况的地方,如下图所示。
这里,first和last都是private final的,但在重写的equals中都可以直接通过n.first和n.last访问。
这种情况是之前在编程中未曾发现的,如果可以通过这种方式访问内部的表示的话,也就免去了在equals方法内部调用getname、getjob和getphone方法才能得到相应的表示的麻烦,更加清晰、明了。