0

Class Paren contains only an int.

public class Paren 
{
    private int _val=0;

    public Paren()
    {
        _val=10;
    }

    public Paren(int val)
    {
        _val=val;
    }

    public String toString()
    {
        return "val=" + _val ;
    }
}   

Class Chil extends class Paren, also contains a String and overloads the equals method 3 times: 1. takes an Object parameter 2. takes a Paren parameter 3. takes a Chil parameter

public class Chil extends Paren 
{
    private String _st;

    public Chil()
    {
        _st="child";
    }

    public Chil(String st, int val)
    {
        super(val);
        _st=st;
    }

    public String getSt()
    {
        return _st;
    }

    public boolean equals (Object ob) 
    {
        if ((ob != null) && (ob instanceof Chil))
        {
            if (_st.equals(((Chil)ob)._st) &&
            (getVal() == ((Chil)ob).getVal()))
            return true;
        }
        return false;
    }

    public boolean equals (Paren ob) // shita 2
    {
        if ((ob != null) && (ob instanceof Chil))
        {
            if (_st.equals(((Chil)ob)._st) &&
            (getVal() == ((Chil)ob).getVal()))
            return true;
        }
        return false;
    }

    public boolean equals (Chil ob) 
    {
        if (ob != null)
        {
            if (_st.equals(((Chil)ob)._st) &&
            (getVal() == ((Chil)ob).getVal()))
            return true;
        }
        return false;
    }
}

I instantiate objects thusly:

Paren A = new Chil();
Chil B = new Chil();

A polymorphically holds a Chil object. When I call

A.equals(B) 

the call jumps to 1. equals() that takes an Object parameter

If A is a Chil and B is a Chil, why doesn't it go to the equals() that takes a Chil parameter?

Winter
  • 3,894
  • 7
  • 24
  • 56
  • 1
    It can't call the overloaded `equals` methods in `Chil`, because the variable is of type `Paren`, and the overloaded methods are not declared for `Paren`. It resolves to `equals(Object)` (which `Paren` inherits from `Object`), and then at runtime the overridden implementation of `equals(Object)` in `Chil` is called. – khelwood Dec 19 '16 at 13:24
  • you declared all of the overloaded equals methods in Chill but you call it from Paren reference so your A reference can only see equals(Object obj) from new Chil(); if you call B.equals(A); you will get equals(Paren obj); – Sarkhan Dec 19 '16 at 13:26
  • Method signature is picked at *compilation* time. Polymoprhism only guarantees that code which will be executed for that method will be searched at runtime based on *actual object type held in reference variable*. For `Paren A` when you use `A.equals(B)` compiler cant assume what will be actual type held in `A` so he allows only method signatures available for `Paren` class which is `equals(Object)` inherited from Object class. Later you overwritten this method in `Chil` class so via polymoprhism you invoked that overwritten code. – Pshemo Dec 19 '16 at 13:43

2 Answers2

0

When the compiler sees A.equals(B) it searches for methods named equals defined in Paren class (the compile time type of A) or the ancestors of Paren class. It finds equals(Object) in the Object class. It doesn't find the equals methods defined in Chil class, so it can't choose the methods having the equals (Paren ob) or equals (Chil ob) signatures.

This is method overloading, determined at compile time.

At runtime, the JVM sees that the runtime type of A is Chil and that Chil overrides equals (Object ob), so it executes Chil's equals (Object ob).

Eran
  • 387,369
  • 54
  • 702
  • 768
0

A acts like Paren which doesn't have a equals (Chil ob). What it has is equals(Object o) from Object class. Hence, at compile time, compiler binds this call to equals(Object o) and hence tis invoked.

Gurwinder Singh
  • 38,557
  • 6
  • 51
  • 76