Java 以父类和子类作为参数的方法重载

Java 以父类和子类作为参数的方法重载,java,inheritance,polymorphism,overloading,Java,Inheritance,Polymorphism,Overloading,我有三个班,分别是祖父母,父母和孩子,其中 子女扩展父母和父母扩展祖父母 public class Main { void test(GrandParent gp){System.out.println("GrandParent");} void test(Parent p){System.out.println("Parent");} public static void main(String args[]){ GrandParent obj = n

我有三个班,分别是
祖父母
父母
孩子
,其中
子女扩展父母
父母扩展祖父母

public class Main {
    void test(GrandParent gp){System.out.println("GrandParent");}
    void test(Parent p){System.out.println("Parent");}

    public static void main(String args[]){
        GrandParent obj = new Child();
        Main mainObj = new Main();
        mainObj.test(obj);  // This calls test(GrandParent gp)

        mainObj.test(new Child()); // This calss test(Parent gp)
    }
}

在上面的代码中,对
test()
方法的两次调用中,都使用
Child
对象调用不同的方法。一种是编译时绑定,另一种是运行时绑定。这听起来有点奇怪。您如何解释这一点?

方法重载是编译时多态性

方法重写是运行时多态性

在本例中,您正在重载类
Main
的两个实例方法

但是,由于我假定在您的上下文中
Child
扩展了
Parent
new Child()instanceof Parent==true
,因此
Child
的实例是参数类型为
Parent
的方法的有效参数

在第一种情况下,在方法
test
中传递一个引用类型
GrandParent
,并找到确切的类型


在第二种情况下,在方法
test
中传递引用类型
Child
。最接近的匹配是
Parent
,因此调用
test(Parent p)

重载意味着相同的名称不同的参数。 例如:

      class A {
          public void m1(int a) {
              System.out.println("class A");
          }
          public void m1(int a,int b) {
              System.out.prinln("2 parameter");
          }
      }

这称为方法重载。

我认为您对层次结构感到困惑

事实上你说: 子扩展父-这意味着子“是”父


考虑到这在“真实世界”中没有意义的事实-但是,在代码中有意义-您正在向void test(Parent p)方法提供一个子对象-并且由于子对象是父对象-这就是调用System.out.println(“Parent”)的原因。

嗯,在我看来,这两种情况下都是编译时绑定。。。查看方法重载是如何解决的,应该有一个答案在某个地方浮动,在这两种情况下都是编译时的…但是在这个层次结构中,
子级
也是
祖辈
,对吗?那么,为什么调用的是
Parent
方法而不是
Grandparent
方法呢?从技术上讲,您是对的,但您并没有完全回答OP的问题。我假设给定另一个匹配声明,例如-void test(Object o),提供子对象将调用此方法,因为子类隐式扩展了对象。但是我可能错了。这取决于我是否和你想的一样,如果你做了
test(newchild())
,它实际上不会。如果您将
new Child()
分配给
对象并将其传递,我认为会的。这是事实,但这并不能完全回答OP的问题。