I created an abstract class Fruit, which overrides the equals() method. Then I created a subclass, Orange, which overrides the copy() and the equals() method. In my test file, TestFruit.java, I am creating an array of oranges and testing their methods. I am trying to create a deep copy of orange and do a deep comparison between the parent orange and the copy. However, in my output, the comparison always returns false. I checked the parent and the copy's attributes and they do seem to be the same. Any pointers would be appreciated. I am pretty new to Java and copying. I attached my code below.
Fruit.java:
package juicer;
import copy.Copyable;
public abstract class Fruit implements Copyable, Cloneable
{
    private double mass;
    private boolean isJuicedRemoved;
    protected Fruit(double theMass)
            throws IllegalMassException
    {
        {
            if (theMass <= 0)
            {
                throw new IllegalMassException(theMass);
            }
            else
            {
                this.mass = theMass;
                this.isJuicedRemoved = false;
            }
        }
    }
    protected Fruit(Fruit fruit)
    {
        this.mass = fruit.mass;
        this.isJuicedRemoved = fruit.isJuicedRemoved;
    }
    public double getMass()
    {
        return mass;
    }
    public boolean getIsJuicedExtracted()
    {
        return isJuicedRemoved;
    }
    protected void setMass(double value)
    {
        this.mass = value;
    }
    protected abstract double juiceRatio();
    public double extractJuice()
    {
        double liquidMass = amountJuice();
        if (!isJuicedRemoved)
        {
            isJuicedRemoved = true;
            mass -= liquidMass;
        }
        return liquidMass;
    }
    public double amountJuice()
    {
        if (isJuicedRemoved) return 0.0;
        return mass * juiceRatio();
    }
    @Override
    public boolean equals(Object obj)
    {
        // Steps to override the equals() method():
        // Step 1: Test if obj is an instance of Fruit.
        //         If it is not, then return false.
        if (!(obj instanceof Fruit)) return false;
        // Step 2: Cast obj to an Fruit.
        Fruit rhs = (Fruit)obj;
        // Step 3: Test if the data fields of the invoking object are
        //         equal to the ones in rhs using a deep comparison
        //         and return this result.
        return super.equals(obj) && // test for equality in the super class
                mass == rhs.mass &&
                isJuicedRemoved == rhs.isJuicedRemoved;
    }
    @Override
    public int hashCode()
    {
        int result = super.hashCode();
        result = 31*result + Double.hashCode(mass);
        result = 31*result + Boolean.hashCode(isJuicedRemoved);
        return result;
    }
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        Fruit objectClone = (Fruit)super.clone();
        objectClone.mass = mass;
        objectClone.isJuicedRemoved = isJuicedRemoved;
        return objectClone;
    }
    @Override
    public String toString()
    {
        return "\tmass = " + mass +
                "\n\tisJuiceExtracted = " + isJuicedRemoved + "\n";
    }
}
Orange.java:
package juicer;
public class Orange extends Fruit
{
    public Orange(double mass)
    {
        super(mass);
    }
    // copy constructor
    public Orange(Orange other)
    {
        super(other);
    }
    @Override
    protected double juiceRatio()
    {
        return 0.87;
    }
    @Override
    public boolean equals(Object obj)
    {
        // Steps to override the equals() method():
        // Step 1: Test if obj is an instance of Orange.
        //         If it is not, then return false.
        if (!(obj instanceof Orange)) return false;
        // Step 2: Cast obj to an Orange.
        // This step is not needed since the only data fields this
        // class has are the ones it inherits.
        // Step 3: Test if the data fields of the invoking object are
        //         equal to the ones in rhs using a deep comparison
        //         and return this result.
        return super.equals(obj);
    }
    @Override
    public Object copy()
    {
        return new Orange(this);
    }
    @Override
    public String toString()
    {
        return "Orange:\n" + super.toString();
    }
}
TestFruit.java:
package test;
import juicer.*;
import java.util.Random;
public class TestFruit
{
    public static void main(String[] args)
    {
        Orange[] oranges = new Orange[1];
        //Random double generator for mass
        Random rd = new Random();
        //create oranges
        for (int i = 0; i <= oranges.length - 1; i++ )
        {
            oranges[i] = new Orange(rd.nextDouble());
        }
        for (Orange orange : oranges)
        {
            Orange orangeCopy = new Orange(orange);
            if (orange == orangeCopy)
            {
                System.out.print("The comparison is true!");
            }
            else
            {
                System.out.print("Does not match.");
            }
        }
    }
}
 
    