当前位置: 首页 > 面试题库 >

Java静态和动态绑定,重载

弘伟彦
2023-03-14
问题内容

我正在为测试做练习,并且遇到了有关重载以及静态和动态绑定的练习。询问以下代码的输出:

class Moe {
    public void print(Moe p) {
        System.out.println("Moe 1");
    }
}

class Larry extends Moe {
    public void print(Moe p) {
        System.out.println("Larry 1");
    }
    public void print(Larry l) {
        System.out.println("Larry 2");
    }
}

class Curly extends Larry {
    public void print(Moe p) {
        System.out.println("Curly 1");
    }
    public void print(Larry l) {
        System.out.println("Curly 2");
    }
    public void print(Curly b) {
        System.out.println("Curly 3");
    }
}

class Overloading {
    public static void main (String [] args) {
        Larry stooge1 = new Curly();
        Moe stooge2 = new Larry();
        Moe stooge3 = new Curly();
        Curly stooge4 = new Curly();
        Larry stooge5 = new Larry();

        stooge1.print(new Moe());
        stooge1.print(new Curly());
        stooge1.print(new Larry());
        stooge2.print(new Curly());
        stooge3.print(new Curly());
        stooge3.print(new Larry());
        stooge5.print(new Curly());
    }
}

认为 我获得了第一个,但在其他方面我完全迷失了。这是我解决第一个问题的方法:

在运行时,类型stooge1Curly,因此我们调用Curly的print方法。由于我们传递了Moe要打印的类型的对象,因此在Moe中运行了具有参数类型的相应打印方法Curly。该方法的输出为Curly 1,正确答案。

但是,当我将这种技术应用于以下几行时,我得到的答案是错误的。有人可以解释一下这个概念在Java中的工作原理吗?

该代码的正确输出是:

Curly 1
Curly 2
Curly 2
Larry 1
Curly 1
Curly 1
Larry 2

问题答案:

静态绑定在编译时发生,动态绑定在运行时发生。

  • 静态绑定 负责选择应执行的方法的 签名 (名称和参数类型)。它用

    • __方法 名称
    • 带有参数的变量类型(编译器不假定运行时实际的对象变量将保留,他选择了能够处理所有可能情况的签名)。

编译器会选择签名 从该方法被调用变量的类型 ,所以Object o = "abc";不会
让你调用o.substring(1,2);,因为编译器将无法找到substring(int, int)在签名Object类(这是类型o上的变量substring被调用的方法)。

  • 动态绑定* 负责在编译时 _查找和调用 _通过静态绑定选择的方法的 _ 代码* 。它将尝试查找变量持有的 _实际实例 类型的方法代码。换句话说,如果有的Animal a = new Cat(); a.makeSound();话,可以期望得到结果,"Mew"因为在运行时JVM将搜索并调用makeSoundCat类开始的代码。如果在该类中未提供实现,则JVM将在祖先中搜索它,直到找到从其继承的继承。

我对示例中的类和变量进行了重命名,以期使其更具可读性:

class A {
    public void print(A a) {
        System.out.println("A.print(A)");
    }
}

class B extends A {
    public void print(A a) {
        System.out.println("B.print(A)");
    }
    public void print(B b) {
        System.out.println("B.print(B)");
    }
}

class C extends B {
    public void print(A a) {
        System.out.println("C.print(A)");
    }
    public void print(B b) {
        System.out.println("C.print(B)");
    }
    public void print(C c) {
        System.out.println("C.print(C)");
    }
}

class OverloadingDemo {
    public static void main (String [] args) {
        A ab = new B();
        A ac = new C();
        B bb = new B();
        B bc = new C();

        bc.print(new A());
        bc.print(new C());
        bc.print(new B());
        ab.print(new C());
        ac.print(new C());
        ac.print(new B());
        bb.print(new C());
    }
}

(变量命名-> X持有类型的实例的类型的变量Y被命名为xy)。

所以,当我们执行

bc.print(new A());
  • 静态绑定将尝试找到可处理type实例的 可用的 最佳print方法签名。在这种情况下将是。 BA``print(A)
  • 之后,动态绑定将在类中搜索此方法的 代码C(因为这是bc变量持有的实例的类型),这意味着我们将看到C.print(A)

同样的情况 bc.print(new C());

  • 静态绑定将尝试为类中可用printC参数找到最佳方法B,这Cprint(B)因为(因为那里没有print(C),并且B是最接近的超类型)。
  • 所以现在动态绑定知道要在C类中查找哪种方法(因为这是bc保存的实例)。

因此它将调用C.print(B)



 类似资料:
  • 我想我得到了第一个,但在其他方面我完全迷失了。我是这样解决第一个问题的: 在运行时,的类型是,所以我们调用curly的print方法。因为我们将类型的对象传递给print,所以相应的参数类型为的print方法在中运行。此方法的输出是,正确答案。 然而,当我将此技术应用到以下行时,我最终得到了错误的答案。有人能解释一下这个概念在Java中到底是如何工作的吗? 代码的正确输出是:

  • 问题内容: 我对动态绑定和静态绑定感到非常困惑。我已经读过,在编译时确定对象的类型称为静态绑定,而在运行时确定它的称为动态绑定。 下面的代码会发生什么: 静态绑定还是动态绑定? 这表明什么样的多态性? 问题答案: 您的示例是 动态绑定 ,因为在运行时确定类型是什么,并调用适当的方法。 现在假设您也具有以下两种方法: 即使您更改为 这将打印出来,因为对的调用使用 静态绑定 ,并且编译器仅知道其类型。

  • 请有人给我解释一下输出的最后6行是如何打印出来的。我知道,由于静态绑定,前三行打印适当。 我不知道为什么第5行给出了输出,因为它是Ipod类型的,它没有任何歌曲方法,但它仍然打印输出。代码如下: 输出如下所示:

  • 本文向大家介绍浅谈Java中的重载,重写,多态,静态绑定、动态绑定,包括了浅谈Java中的重载,重写,多态,静态绑定、动态绑定的使用技巧和注意事项,需要的朋友参考一下 本文主要研究的是关于Java中重载,重写,多态,静态绑定、动态绑定的相关内容,具体如下。 重载,英文名是overload,是指在一个类中定义了一个以上具有相同名称的方法,这些方法的参数个数、参数类型和顺序不能相同。返回类型可以相同,

  • 我们知道静态绑定发生在私有、静态、最终和重载的方法上,而动态绑定发生在被覆盖的方法上。但是如果我的方法只是公共的,它既不是静态的,也不是覆盖和重载的怎么办? 有人能给我解释一下print()的绑定会怎样,因为它既没有重载也没有被覆盖。

  • 静态绑定还是动态绑定? 这显示了什么样的多态性?