import java.util.*;
import java.lang.*;

class Main
{
    public static abstract class AbstractClass {
        private String id;
        
        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++;
    }
}    
    
    
	public static void main (String[] args) throws java.lang.Exception
	{
        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 ));
	}
}