Java 超驰和过载

Java 超驰和过载,java,Java,我的问题是:为什么a4.equals(a2)导致method1执行而不是method2? a2指向AA,它是参数。 关于a2.equals(b1)也是一样的。 似乎当它不指向BB(指向所有方法都等于的类)时,它只会导致method1执行,而方法获得哪种类型的参数并不重要 public class AA { public int getVal() { return 5; } } public class BB extends AA { private

我的问题是:为什么
a4.equals(a2)
导致
method1
执行而不是
method2
a2
指向
AA
,它是参数。 关于
a2.equals(b1)
也是一样的。 似乎当它不指向
BB
(指向所有
方法都等于
的类)时,它只会导致
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));
    }
}

AA
类已知的唯一
equals
方法是
Object
equals
,它接受一个
Object
参数。因此,在调用
a4.equals(a2)
a2.equals(b1)
时,只能调用
public boolean equals(Object ob)
,因为
a2
a4
的编译时类型都是
AA


在运行时调用的方法是“method1”,因为它覆盖
对象的
等于
。只能对编译时类型为
BB
的引用调用
public boolean equals(AA ob)
public boolean equals(BB ob)
重载,因为方法重载是基于调用该方法的对象的编译时类型来解决的。如果你调用
b1.equals()
你会看到你选择的其他方法,因为将使用方法重载。

如果可能,你能给我指一个链接,我可以在那里更详细地了解上述概念。@Abhishek只需谷歌“JLS方法重载解析”和“JLS方法重写”,但当调用a4.equals(a2)时,a2指向AA,公共布尔等于(对象ob)接受对象而不是AA。所以它会在运行时自动向上投射?@Arthur它不需要进行任何投射
AA
只有一个
equals
方法-
公共布尔值equals(对象ob)
。由于可以将任何
对象
传递给该方法(包括
AA
对象),
a4.equals(a2)
可以执行
public boolean equals(Object ob)
,这就是它所做的。@Arthur因为任何类都是
对象
的子类,所以可以将任何类的任何实例传递给该方法
public boolean equals(对象ob)
。无论
a2
的类型是什么。“为什么a4.equals(a2)导致method1执行而不是method2?”因为
中的
equals(AA AA)
BB
中不是方法
equals(对象o)
的重写,因为参数类型不匹配。“似乎当它不指向BB(指向所有相等方法所在的类)时,它只会导致method1执行,而不管方法获得哪种类型的参数。“完全正确。您只能对其中声明的类型调用方法。相同的名称和相同的参数值是不够的,参数的类型也必须以相同的顺序匹配。顺便说一句:在
instanceof
之前检查非空性是多余的:
null instanceof AnyClass