公设基础equals
package com.KAstandardization.GeneralContract;
import java.awt.*;
/**
* equlas
* 实现了等价关系(equivalence relation)
* 有一种值类不需要覆盖equlas方法,即实例受控确保 每个值至多只存在一个对象 的类
* 枚举类型就属于这种类,对于这样的类而言, 逻辑相同 与 对象等同 是一回事!
* 覆盖equals方法的通用约定
*
* 1.自反性(reflexive) 自己跟自己的比较必须返回true
*
* 2.对称性(symmetric) x=y那么y=z
*
* 3.传递性(transitive) x=y同时y=z那么x=z
*
* 4.一致性(consistent) 只要equals比较多的对象没有被修改那么 第一次x=y那么接下来的无论多少次x都等于y
*
* 5.对于x.equlas(null)必须返回false x不为null
*/
public class Equals_HashCode_ToString
{
/**
* 类是私有的或者包级私有的,可以确定它的equals方法永远不会被调用
* 在这种情况下,无疑是应该覆盖equals方法的,以防止它被意外调用
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
throw new AssertionError();
}
}
/**
* 对称性
*/
class Equals2_1
{
private final String str;
public Equals2_1(String str)
{
if (str == null)
throw new NullPointerException();
this.str = str;
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof Equals2_1)
return str.equalsIgnoreCase(((Equals2_1) obj).str);
if (obj instanceof String)
return str.equalsIgnoreCase((String) obj);
return false;
}
public static void main(String[] args) {
Equals2_1 e = new Equals2_1("Wang");
String s = "wang";
boolean test = e.equals(s);
System.out.println(test);
boolean test2 = s.equals(e);
System.out.println(test2);
}
}
/**
* 一旦违反了equlas约定,当其他对象面对你的对象时,你完全不知道这些对象的行为会怎么样
* 解决这个问题,只需把企图与String互操作的这段代码从equlas方法中去掉即可,这样做之后,就可以重构该方法,
* 使它变成一条单独的返回语句
*/
class Equlas2_2
{
private final String str;
public Equlas2_2(String str)
{
if (str == null)
throw new NullPointerException();
this.str = str;
}
@Override
public boolean equals(Object obj)
{
return obj instanceof Equlas2_2 && ((Equlas2_2) obj).str.equalsIgnoreCase(str);
}
public static void main(String[] args) {
Equlas2_2 e = new Equlas2_2("Wang");
String s = "wang";
boolean test = e.equals(s);
System.out.println(test);
boolean test2 = s.equals(e);
System.out.println(test2);
}
}
class Equlas3
{
private final int x;
private final int y;
public Equlas3(int x, int y)
{
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Equlas3))
return false;
Equlas3 e = (Equlas3)o;
return e.x == x && e.y == y;
}
}
/**
* 违反了对称性
*/
class ColorEqulas3 extends Equlas3
{
private final Color color;
public ColorEqulas3(int x, int y, Color color)
{
super(x, y);
this.color = color;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof ColorEqulas3))
return false;
return super.equals(o) && ((ColorEqulas3) o).color == color;
}
//违反了对称性
public static void main(String[] args)
{
Equlas3 e = new Equlas3(1,2);
ColorEqulas3 c = new ColorEqulas3(1,2,Color.BLACK);
System.out.println(e.equals(c));
System.out.println(c.equals(e));
}
}
/**
* 复合
* 不在让Color扩展E3,而是在Color中加入一个私有的E3域,以及一个公有的视图(view)方法
* 此方法返回一个与该有色点处在相同位置的普通E3对象.
* !!!
* 你可以在一个抽象(abstract)类的子类中增加新的值组件,而不会违反equals约定
* 不能直接创建超类的实例
*/
class Equlas4
{
private final Equlas3 equlas3;
private final Color color;
public Equlas4(int x, int y, Color color)
{
if (color == null)
throw new NullPointerException();
equlas3 = new Equlas3(x, y);
this.color = color;
}
public Equlas3 asE3()
{
return equlas3;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Equlas4))
return false;
Equlas4 e4 = (Equlas4) o;
return e4.equlas3.equals(equlas3) && e4.color.equals(color);
}
public static void main(String[] args)
{
Equlas3 e3 = new Equlas3(1,2);
Equlas4 e4 = new Equlas4(1,2,Color.BLUE);
Equlas3 equlas3 = e4.asE3();
System.out.println(e3.equals(equlas3));
}
}