import java.util.*;
import java.lang.*;
class Main
{
public static abstract class AbstractClass {
AbstractClass
( String id0
) { id
= id0
; }
public boolean equals
(Object other
) { return other != null && other.getClass().equals(getClass())
&& id.equals(((AbstractClass) other).id);
}
}
public static class ConcreteClassOne extends AbstractClass
{
private final AbstractClass parent;
public ConcreteClassOne
( String anId, AbstractClass aParent
) {
super( anId );
parent = aParent;
}
}
public static class ConcreteClassTwo extends ConcreteClassOne
{
private static int nextTrackingNo = 0;
private final int trackingNo;
public ConcreteClassTwo
( String anId
) {
super( anId, null );
trackingNo= getNextTrackingNo();
}
public boolean equals
(Object other
) { boolean rv = super.equals( other );
if ( other instanceof ConcreteClassTwo ) {
rv = rv && (this.trackingNo == ((ConcreteClassTwo) other).trackingNo);
}
return rv;
}
private int getNextTrackingNo() {
return nextTrackingNo++;
}
}
{
ConcreteClassTwo c2a = new ConcreteClassTwo( "one" );
ConcreteClassTwo c2b = new ConcreteClassTwo( "one" );
ConcreteClassOne c1 = new ConcreteClassOne( "one", null );
System.
out.
println( c2a.
equals( c1
)); System.
out.
println( c1.
equals( c2b
)); System.
out.
println( c2a.
equals( c2b
)); }
}
aW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CgpjbGFzcyBNYWluCnsKICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RDbGFzcyB7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgaWQ7CiAgICAgICAgCiAgICAgICAgQWJzdHJhY3RDbGFzcyggU3RyaW5nIGlkMCApIHsgaWQgPSBpZDA7IH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gb3RoZXIgIT0gbnVsbCAmJiBvdGhlci5nZXRDbGFzcygpLmVxdWFscyhnZXRDbGFzcygpKQogICAgICAgICAgICAgICAgICAgICYmIGlkLmVxdWFscygoKEFic3RyYWN0Q2xhc3MpIG90aGVyKS5pZCk7CiAgICAgICAgfQoKICAgIH0KICAgIAogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb25jcmV0ZUNsYXNzT25lIGV4dGVuZHMgQWJzdHJhY3RDbGFzcwogICAgewogIHByaXZhdGUgZmluYWwgQWJzdHJhY3RDbGFzcyBwYXJlbnQ7CgogIHB1YmxpYyBDb25jcmV0ZUNsYXNzT25lKCBTdHJpbmcgYW5JZCwgQWJzdHJhY3RDbGFzcyBhUGFyZW50ICkKICB7CiAgICBzdXBlciggYW5JZCApOwoKICAgIHBhcmVudCA9IGFQYXJlbnQ7CiAgfQp9CgpwdWJsaWMgc3RhdGljIGNsYXNzIENvbmNyZXRlQ2xhc3NUd28gZXh0ZW5kcyBDb25jcmV0ZUNsYXNzT25lCnsKICBwcml2YXRlIHN0YXRpYyBpbnQgbmV4dFRyYWNraW5nTm8gPSAwOwoKICBwcml2YXRlIGZpbmFsIGludCB0cmFja2luZ05vOwoKICBwdWJsaWMgQ29uY3JldGVDbGFzc1R3byAoIFN0cmluZyBhbklkICkKICB7CiAgICBzdXBlciggYW5JZCwgbnVsbCApOwoKICAgIHRyYWNraW5nTm89IGdldE5leHRUcmFja2luZ05vKCk7CiAgfQoKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICBib29sZWFuIHJ2ID0gc3VwZXIuZXF1YWxzKCBvdGhlciApOwogICAgICAgIGlmICggb3RoZXIgaW5zdGFuY2VvZiBDb25jcmV0ZUNsYXNzVHdvICkgewogICAgICAgICAgIHJ2ID0gcnYgJiYgKHRoaXMudHJhY2tpbmdObyA9PSAoKENvbmNyZXRlQ2xhc3NUd28pIG90aGVyKS50cmFja2luZ05vKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJ2OwogICAgfQogICAgCiAgICBwcml2YXRlIGludCBnZXROZXh0VHJhY2tpbmdObygpIHsKICAgICAgICAgcmV0dXJuIG5leHRUcmFja2luZ05vKys7CiAgICB9Cn0gICAgCiAgICAKICAgIAoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CiAgICAgICAgQ29uY3JldGVDbGFzc1R3byBjMmEgPSBuZXcgQ29uY3JldGVDbGFzc1R3byggIm9uZSIgKTsKICAgICAgICBDb25jcmV0ZUNsYXNzVHdvIGMyYiA9IG5ldyBDb25jcmV0ZUNsYXNzVHdvKCAib25lIiApOwogICAgICAgIENvbmNyZXRlQ2xhc3NPbmUgYzEgID0gbmV3IENvbmNyZXRlQ2xhc3NPbmUoICJvbmUiLCBudWxsICk7CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCBjMmEuZXF1YWxzKCBjMSApKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIGMxLmVxdWFscyggYzJiICkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggYzJhLmVxdWFscyggYzJiICkpOwoJfQp9