Переопределение и перегрузка


Мой вопрос: почему a4.equals(a2) заставляет method1 выполнять, а не method2? a2 указывает на AA, и это параметр. И то же самое о a2.equals(b1). Похоже, что когда он не указывает на BB (класс, в котором находятся все методы equals), он вызовет только method1 для выполнения, и не имеет значения, какой тип параметра получает метод.

public class AA
{
    public int getVal()
    {
       return 5;
    }
}

public class BB extends AA
{
    private String _st = "bb";

    public boolean equals(Object ob)  //method1
    {
      System.out.println("Method 1");
        if((ob != null) && (ob instanceof BB))
        {
            if(_st.equals(((BB)ob)._st) && (getVal() == ((BB)ob).getVal()))
                return true;
        }
        return false;
    }


    public boolean equals(AA ob)  //method2
    {
    System.out.println("Method 2");
        if((ob != null) && (ob instanceof BB))
        {
            if(_st.equals(((BB)ob)._st) && (getVal() == ((BB)ob).getVal()))
            return true;
        }
        return false;
    }

    public boolean equals(BB ob)  //method3
    {
        System.out.println("Method 3");
        if(ob != null)
            if(_st.equals(((BB)ob)._st) && (getVal() == ((BB)ob).getVal()))
                return true;

        return false;
    }
}

public class Driver
{
    public static void main(String[] args)
    {
        AA a2 = new BB();
        AA a4 = new BB();   
        BB b1 = new BB();  

        System.out.println(a4.equals(a2));
        System.out.println(a2.equals(b1));
    }
}
1   4  

1 ответа:

Единственный метод equals, известный классу AA, - это метод Object's equals, который принимает аргумент Object. Поэтому только public boolean equals(Object ob) может быть вызван при вызове a4.equals(a2) или a2.equals(b1), так как тип времени компиляции обоих a2 и a4 равен AA.

Метод, который вызывается во время выполнения, является вашим "method1", так как он переопределяет Object's equals. Перегрузки public boolean equals(AA ob) и public boolean equals(BB ob) могут быть вызваны только для ссылок, тип времени компиляции которых BB, так как перегрузка метода разрешена на основе времени компиляции тип объекта, для которого вызывается метод. Если вы вызовете b1.equals(), вы увидите, что выбраны другие методы, так как будет использоваться перегрузка метода.