Java 运行时多态性

Java 运行时多态性,java,polymorphism,Java,Polymorphism,假设我有甲级 public class A { public void method() { //do stuff } } 还有另一个B级 public class B extends A { public void method() { //do other stuff } } 现在我有以下陈述: A a = new B(); a.method(); 这是运行时多态性的一个例子吗?如果是,则在编译时没有对引用

假设我有甲级

public class A
{
    public void method()
    {
        //do stuff
    }
}
还有另一个B级

public class B extends A
{
    public void method()
    {
        //do other stuff
    }
}
现在我有以下陈述:

A a = new B();
a.method();
这是运行时多态性的一个例子吗?如果是,则在编译时没有对引用
a
进行绑定?

编译器会告诉您这无法工作,因为a和B之间没有允许您编写
a=new B()的关系

B要么必须扩展A,要么两者都必须实现一个带有
void method()
的公共接口

您可以通过使用编译器来快速回答这个问题。做一个实验主义者——它比论坛快

更新:


既然B扩展了A,它就工作了。您关心的绑定,动态绑定,是在运行时完成的。变量“a”的静态编译时类型为a类;在运行时,它被动态绑定到类型B的引用。是的,我认为这是多态性的一个例子。

您给出的代码示例是不合法的,所以我猜答案是它不是一种多态性。

您不能将一个类分配给这样一个不相关类型的变量。我猜你可能想让B从A中派生出来?

应该是这样的

公共类B扩展了{
公共作废方法()
{
//做其他事情
}}


如果它正在编译,则将调用
B::method()
。(仅当您更改代码以使B类继承A类时)

在本例中,您使用对象就像它只是一个A一样,但是如果某些方法在B中被省略,那么将调用这些方法,而不是A的方法

这是运行时多态性的一个例子吗

在编辑时:是,这将是运行时多态性,因为实际执行的方法取决于分配给
a
的内容

编辑:

如果
method()
是静态的,那么调用
a.method()
总是会导致调用
a
的版本。但是,您只需编写
A.method()
,如果不这样做,任何合适的IDE都会警告您这一点(因为在实例上调用静态方法可能会产生误导)

结束编辑

编译时多态性将是一种重载机制,即编译器根据它对所传递参数的了解来决定是使用
somethod(Number)
还是
somethod(Integer)
(如果您传递一个
双精度
或仅传递一个
数字
,它将是第一个,如果传递一个
整数
它将是第二个)

如果是,那么在编译时是否没有对引用a进行绑定


你的确切意思是什么?请注意
a
的类型将是
a
,因此你可以在运行时分配扩展
a
的所有内容。如果分配的值不是
a
(您可能会用强制转换欺骗编译器,但这是邪恶的,如果这破坏了您的程序,您将收到警告;)

我正等着把我的答案放到另一篇文章中,放到一个分类更准确的问题中。你的问题符合这个概念,我已经试着详细解释了。但是,因为我不知道链接是如何回答的,所以我将把完整的脚本复制/粘贴到这里……请仔细阅读,你会理解关于你的问题的所有内容莱姆,你已经问过了


假设编译器必须解析如下调用:*

A=新AA();//假设AA是类A的某个子类
a->someFunc();//我们正在调用

*

现在,编译器将有条不紊地进行以下步骤

1.)首先,编译器知道变量a的声明类型,因此它将检查对象a的声明类型(
lets call this,class a,暂称为
)是否有名为someFunc()的方法它必须是公共的。这个方法可以在
类A
中声明,也可以是从类A的基类之一派生的方法,但这对编译器来说并不重要,它只是检查它是否存在,并且它的访问说明符是
公共的

  • 不用说,此步骤中的任何错误都会引发编译器错误
2.)其次,一旦该方法被验证为类a的一部分,编译器必须解析对正确方法的调用,因为许多方法可能具有相同的名称(由于函数重载)。解析正确方法的过程称为
重载解析
。编译器通过将被调用方法的签名与属于类的所有重载方法相匹配来实现这一点。因此,在所有
someFunc()中
只有正确的someFunc()(将签名与被调用方法相匹配)将被发现并进一步考虑

3.)现在是困难的部分,很有可能someFunc()在类A的一个子类中被重写(
我们调用这个类AA,不用说它是A的某个子类),而变量A(声明为A类型)实际上可能引用了类AA的对象,现在,如果将Soad函数()方法声明为“类型>代码>虚拟/C++ >,则在基类(即类A)和某个函数()中已经被A的子类(ES)所覆盖(在AA和A类之间),必须从编译器中找到正确的Soad函数()的版本。
  • 现在,假设你是编译器,你的任务是查找类
    AA
    是否有此方法。显然,类AA将有此方法,因为它是a的子类,并且类a中a的公共访问已在步骤1中由编译器验证!!!。但是,如前一段所述unc()可能已被覆盖