import java.util.*;
import java.lang.*;
import java.io.*;
abstract class A
{
final int value;
protected A(int value) { this.value = value; }
public int hashCode() { return value; }
public boolean equals
(Object o
) { if (o == this) return true; if (o == null) return false;
if (!(o instanceof A)) return false;
return value == ((A)o).value; // ? extend A class???
}
}
class B extends A {
public B
(int value,
String name
) { super(value
); this.
name = name
; } public int hashCode() { return name.hashCode() ^ super.hashCode(); }
public boolean equals
(Object o
) { if (!super.equals(o)) return false;
if (!(o instanceof B)) return false;
return name.equals(((B)o).name); // ? extend B class???
}
}
class C extends A {
public C(int value) { super(value); }
// really need to override method equals
}
abstract class X
{
final int value;
protected X(int value) { this.value = value; }
public int hashCode() { return value; }
public boolean equals
(Object o
) { if (o == this) return true; if (o == null) return false;
if (o.getClass() != getClass()) return false;
return value == ((X)o).value;
}
}
class Y extends X {
public Y
(int value,
String name
) { super(value
); this.
name = name
; } public int hashCode() { return name.hashCode() ^ super.hashCode(); }
public boolean equals
(Object o
) { if (!super.equals(o)) return false;
return name.equals(((Y)o).name); // depend calling getClass in super.equals
}
}
class Z extends X {
public Z(int value) { super(value); }
// depend calling getClass in super.equals
}
class Ideone
{
{
A a1 = new B(123, "hoge");
A a2 = new B(123, "hoge");
A a3 = new C(123);
A a4 = new C(123);
println("a1 == a2 (want true): " + a1.equals(a2));
println("a1 == a3 (want false): " + a1.equals(a3));
println("a3 == a1 (want false): " + a3.equals(a1));
println("a3 == a4 (want true): " + a3.equals(a4));
println("---------");
X x1 = new Y(123, "hoge");
X x2 = new Y(123, "hoge");
X x3 = new Z(123);
X x4 = new Z(123);
println("x1 == x2 (want true): " + x1.equals(x2));
println("x1 == x3 (want false): " + x1.equals(x3));
println("x3 == x1 (want false): " + x3.equals(x1));
println("x3 == x4 (want true): " + x3.equals(x4));
}
}