java编写salary函数_完美重写Java的equals函数

首先看一下String的equals()函数的重写:

1 /**

2 * Compares this string to the specified object. The result is {@code

3 * true} if and only if the argument is not {@codenull} and is a {@code

4 * String} object that represents the same sequence of characters as this5 * object.6 *7 *@paramanObject8 * The object to compare this {@codeString} against9 *10 *@return{@codetrue} if the given object represents a {@codeString}11 * equivalent to this string, {@codefalse} otherwise12 *13 *@see#compareTo(String)14 *@see#equalsIgnoreCase(String)15 */

16 public booleanequals(Object anObject) {17 if (this ==anObject) {18 return true;19 }20 if (anObject instanceofString) {21 String anotherString =(String)anObject;22 int n =value.length;23 if (n ==anotherString.value.length) {24 char v1[] =value;25 char v2[] =anotherString.value;26 int i = 0;27 while (n-- != 0) {28 if (v1[i] !=v2[i])29 return false;30 i++;31 }32 return true;33 }34 }35 return false;36 }

分析一下上面equals()函数:

(1) 首先比较两个对象的引用是否相等,如果两个引用相等,那么两个对象必然相等。

(2) 其次判断anObject是否是String的一个实例 (instanceof关键字的作用是测试一个对象是否是一个类的实例),如果不是则返回false,如果是,则判断obObject的字符串内容是否和this相同:长度是否相等,内容是否相等。

ps: 使用instanceof关键字的问题:当类A是类B的子类时,使用instanceof关键字重写equals()函数就会不符合java语言规范要求equals()方法的“对称性”特性的要求。对称性(对于任何引用x,y,当且仅当y.equals(x)返回true, x.equals(y)也应该返回true)。

一般我们在设计一个类时,需要重写父类的equals方法,在重写这个方法时,需要按照以下几个规则设计:

(1) 自反性:对任意引用值x,x.equals(x)的返回值一定为true.

(2) 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;

(3) 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true

(4) 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变

(5) 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false

那么如何编写一个完美的equals方法呢?

(1)显式参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。

(2)检测this与otherObject是否引用同一个对象:

if(this== otherObject) return true;

(3)检测otherObject是否为null,如果为null,返回false:

if(otherObject == null) return false;

(4)比价this与otherObject是否属于同一个类。

如果equals的语义在每个子类中有所改变,就使用getClass检测 : if(getClass() != otherObject.getClass()) return false;

如果所有的子类都拥有统一的语义,就使用instanceof检测 : if(!(otherObject instanceof ClassName)) return false;

(5) 将otherObject转换为相应的类类型变量:

ClassName other = (ClassName) otherObject;

(6)现在开始对所有需要比较的域进行比较 。使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,就返回true,否则就返回flase。

return field1 ==other.field1&&Objects.equals(field2,other.field2)&& ...;

(7)如果在子类中重新定义equals,就要在其中包含调用 super.equals(other)

举例(摘自Java核心技术)

父类:

1 packageequals;2

3 import java.time.*;4 importjava.util.Objects;5

6 public classEmployee7 {8 privateString name;9 private doublesalary;10 privateLocalDate hireDay;11

12 public Employee(String name, double salary, int year, int month, intday)13 {14 this.name =name;15 this.salary =salary;16 hireDay =LocalDate.of(year, month, day);17 }18

19 publicString getName()20 {21 returnname;22 }23

24 public doublegetSalary()25 {26 returnsalary;27 }28

29 publicLocalDate getHireDay()30 {31 returnhireDay;32 }33

34 public void raiseSalary(doublebyPercent)35 {36 double raise = salary * byPercent / 100;37 salary +=raise;38 }39

40 public booleanequals(Object otherObject)41 {42 //a quick test to see if the objects are identical

43 if (this == otherObject) return true;44

45 //must return false if the explicit parameter is null

46 if (otherObject == null) return false;47

48 //if the classes don't match, they can't be equal

49 if (getClass() != otherObject.getClass()) return false;50

51 //now we know otherObject is a non-null Employee

52 Employee other =(Employee) otherObject;53

54 //test whether the fields have identical values

55 return Objects.equals(name, other.name) && salary == other.salary &&Objects.equals(hireDay, other.hireDay);56 }57

58 public inthashCode()59 {60 returnObjects.hash(name, salary, hireDay);61 }62

63 publicString toString()64 {65 return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" +hireDay66 + "]";67 }68 }

子类:

1 packageequals;2

3 public class Manager extendsEmployee4 {5 private doublebonus;6

7 public Manager(String name, double salary, int year, int month, intday)8 {9 super(name, salary, year, month, day);10 bonus = 0;11 }12

13 public doublegetSalary()14 {15 double baseSalary = super.getSalary();16 return baseSalary +bonus;17 }18

19 public void setBonus(doublebonus)20 {21 this.bonus =bonus;22 }23

24 public booleanequals(Object otherObject)25 {26 if (!super.equals(otherObject)) return false;27 Manager other =(Manager) otherObject;28 //super.equals checked that this and other belong to the same class

29 return bonus ==other.bonus;30 }31

32 public inthashCode()33 {34 return super.hashCode() + 17 * newDouble(bonus).hashCode();35 }36

37 publicString toString()38 {39 return super.toString() + "[bonus=" + bonus + "]";40 }41 }

注意:如果重新定义equals方法,就必须重新定义hashCode方法,以便用户可以将对象插入到散列表中。

如果不太懂(4)到底说的是神马,请看以下摘抄的一篇博文的部分内容,对比instanceof和getClass()的区别,其实getClass会判断实例的类是否相等,而instanceof相等的条件,包括两种情况:(1) 类自身 instanceof 类自身;(2) 子类 instanceof 父类;

1 classA { }2

3 class B extendsA { }4

5 Object o1 = newA();6 Object o2 = newB();7

8 o1 instanceof A => true

9 o1 instanceof B => false

10 o2 instanceof A => true //<================ HERE

11 o2 instanceof B => true //<================ HERE

12

13 o1.getClass().equals(A.class) => true

14 o1.getClass().equals(B.class) => false

15 o2.getClass().equals(A.class) => false //<===============HERE

16 o2.getClass().equals(B.class) => true //<================ HERE

17

18

19

20 getClass() will be useful when you want to make sure your instance is NOT a subclass of the class you are comparing with.

参考博客:https://blog.csdn.net/wu_cai_/article/details/51989033

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值