Figure 9: Illustrates cloning with superclasses

class Super implements Cloneable
{
    private String s1;
    public Super(String s)
    {
        s1 = s;
    }
    public Object clone()
    {
        try
        {
            Super o = (Super)super.clone();
            o.s1 = new String(s1);
            return o;
        }
        catch (CloneNotSupportedException x)
        {
            throw new InternalError();
        }
    }
    public boolean equals(Object o)
    {
        Super sup = (Super)o;
        return s1.equals(sup.s1);
    }
    public String toString()
    {
        return s1;
    }
}

class Sub extends Super
{
    private String s2;
    public Sub(String s)
    {
        super("from Sub");
        s2 = s;
    }
    public Object clone()
    {
        Sub o = (Sub)super.clone();
        o.s2 = new String(s2);
        return o;
    }
    public boolean equals(Object o)
    {
        Sub sub = (Sub)o;
        Super sup = (Super)o;
        return super.equals(sup) && s2.equals(sub.s2);
    }
    public String toString()
    {
        return super.toString() + "/" + s2;
    }
}

class SuperClone
{
    public static void main(String[] args)
    {
        Super sup1 = new Super("Super 1");
        Super sup2 = (Super) sup1.clone();
        System.out.println(sup1 != sup2 && sup1.equals(sup2));
        System.out.println(sup2);

        Sub sub1 = new Sub("Sub 1");
        Sub sub2 = (Sub) sub1.clone();
        System.out.println(sub1 != sub2 && sub1.equals(sub2));
        System.out.println(sub2);
    }
}