1

When I do account1.equals(account2) I have to downcast account2 in the equals() method back to its subclass reference BankAccount compareAccount = (BankAccount)obj; so that I have access to the child classes fields. Once I downcast it, then I can do compareAccount.accountAmount

So now for my question

However in this script I didnt need to do downcast the account1 object to use its fields in the equals() method. I thought since I had upcasted it to object Object account1 = new BankAccount(300.22, 122222) I would not be able to see its fields and therefore, this.accountAmount would not work until I downcasted back to the childclass. So why is this, why does it account1 not need to be downcasted?

public class BankAccountDemo
{
    public static void main(String[] args)
    {

        Object account1 = new BankAccount(300.22, 122222);
        Object account2 = new BankAccount(333.10, 23432434);

        if(account1.equals(account2))
        {
            System.out.println("The objects are equals");
        }
        else
        {
            System.out.println("These objects are not equal");
        }
    }
}

Object class

public class BankAccount
{
    private double accountAmount;
    private int accountNumber;

    public BankAccount(double accountAmount, int accountNumber)
    {
        this.accountAmount = accountAmount;
        this.accountNumber = accountNumber;
    }
    @Override
    public boolean equals(Object obj)
    {
        BankAccount compareAccount = (BankAccount)obj;
        boolean result;
        if (this.accountAmount == compareAccount.accountAmount && this.accountNumber   == compareAccount.accountNumber)
        {
            result = true;
        }
        else
        {
            result = false;
        }
        return result;
    }
}
Nicolas Filotto
  • 39,066
  • 11
  • 82
  • 105
  • What is the parameter type of the single parameter of the `equals` method? – Sotirios Delimanolis Aug 17 '16 at 14:41
  • 2
    Why are you making them `Object`'s? – Rabbit Guy Aug 17 '16 at 14:43
  • The type of `this` is `BankAccount`, not `Object`. – Oliver Charlesworth Aug 17 '16 at 14:45
  • 1
    As a side not, your `BankAccount#equals` violates the [contract for `equals`](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)) . [This SO question](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) is worth reviewing. – bradimus Aug 17 '16 at 14:53
  • *"However in this script I didnt need to do downcast the account1 object to use its fields in the equals() method."* -- You do not need to "downcast" an object to a supertype to use that types method. They are inherited by all derived classes. So you can use `.equals(Object)` on every instance of every class. – Markus Mitterauer Aug 17 '16 at 15:03

1 Answers1

0

The reason is that simply the equals method of BankAccount is called. Therefore, this method has naturally access to all the class' members.

The equals method of BankAccount is called in

Object account1 = new BankAccount(300.22, 122222);
Object account2 = new BankAccount(333.10, 23432434);
if(account1.equals(account2)) { … }

because methods are always virtual, such that the equals method of the instance's type of account1 (BankAccount) is called - not the declared type (Object).

However, you should consider re-thinking your design. Search for explanations how equals should be written. In particular, only cast the parameter to BankAccount after you have assured that it is instanceof BankAccount or at least that BankAccount is assignable from the object's class.

Martin Nyolt
  • 3,706
  • 2
  • 22
  • 33