Java 如果方法调用是动态绑定的,那么为什么编译器会抱怨类型xxx的方法xyz未定义

Java 如果方法调用是动态绑定的,那么为什么编译器会抱怨类型xxx的方法xyz未定义,java,inheritance,Java,Inheritance,如果方法调用是动态绑定的,那么编译器为什么会抱怨 类型B的方法run()未定义 为什么编译器要检查类b中是否存在方法 这是密码 import java.lang.*; public class Program { public static void main(String [] args) { B a = new A(); a.run();//compiler complains at this line. a.p(1

如果方法调用是动态绑定的,那么编译器为什么会抱怨

类型B的方法run()未定义

为什么编译器要检查类b中是否存在方法

这是密码

import java.lang.*;

public class Program
{
    public static void main(String [] args) 
    { 
        B a = new A(); 
          a.run();//compiler complains at this line.
        a.p(10);  
        a.p(10.0); 
    } 
} 
    class B { 
        public void p(int i) 
        { 
            System.out.println(i*2); 
        } 
    }

    class A  extends B{ 
        public void p(int i) 
        { 
            System.out.println(i); 
        } 
        public void run(){

        }
    } 

Java在设计上是一种静态类型的
语言,这意味着编译器必须知道并且能够保证该方法的实现存在于每个具体对象中。(Maxim Shoustin的回答通过一个例子很好地说明了这个设计决策背后的原因。)

如果编译器在没有任何保证的情况下假设一个未知对象恰好有一个特定的方法,那么它将使Java成为鸭子类型的语言。这可能有其自身的优势,但它不符合Java的设计目标


实际上,在静态类型语言中,虚拟(意味着非最终)方法(例如
run()
方法)是动态解析的,但用于解析它们的策略仍然是在编译时编写的。例如,该策略可能涉及读取vTable(包含该对象的虚拟方法的实际实现的地址的表)的正确偏移量,在多态性的许多实现中,利用语言的类型安全性在动态调度期间获得一些性能。

Java是一种设计为静态类型的语言,这意味着编译器必须知道并能够保证该方法的实现存在于每个具体对象中。(Maxim Shoustin的回答通过一个例子很好地说明了这个设计决策背后的原因。)

如果编译器在没有任何保证的情况下假设一个未知对象恰好有一个特定的方法,那么它将使Java成为鸭子类型的语言。这可能有其自身的优势,但它不符合Java的设计目标

实际上,在静态类型语言中,虚拟(意味着非最终)方法(例如
run()
方法)是动态解析的,但用于解析它们的策略仍然是在编译时编写的。例如,在许多多态性实现中,该策略可能涉及读取vTable(一个包含该对象虚拟方法的实际实现地址的表)的正确偏移量——利用语言的类型安全性在动态调度期间获得一些性能。

方法run()对于类型B未定义 这个错误是不言自明的。类型
B
没有名为
.run()

ba=new a()
表示变量
a
的类型为
B
,这就是系统对变量
a
的全部了解

如果执行了
Object s=new String()
,然后执行了
s.toLowerCase()
,它也会失败,因为变量
s
的类型是
Object
而不是
String
类型

无论您的变量是什么类型,都是您可以对该类型调用的唯一行为。

类型B的方法run()未定义 这个错误是不言自明的。类型
B
没有名为
.run()

ba=new a()
表示变量
a
的类型为
B
,这就是系统对变量
a
的全部了解

如果执行了
Object s=new String()
,然后执行了
s.toLowerCase()
,它也会失败,因为变量
s
的类型是
Object
而不是
String
类型

无论您的变量是什么类型,都是您可以对该类型调用的唯一行为。

很容易显示:

让我稍微更改一下您的代码:

  • B=动物
  • A=母牛
更换后:

public class Program
{
    public static void main(String [] args) 
    { 
        Animal a = new Cow(); 
          a.sayMooo();//compiler complains at this line. You try to animal to say "moo"?
          a.speed(10);  
          a.speed(10.0); 
    } 
} 
    class Animal { 
        public void speed(int i) 
        { 
            System.out.println(i*2); 
        } 
    }

    class Cow  extends Animal{ 
        public void p(int i) 
        { 
            System.out.println(i); 
        } 
        public void sayMooo(){

        }
    } 
并非所有动物都是牛

当然

并非所有动物都说“哞哞”

但是

所有奶牛都是动物

很容易展示:

让我稍微更改一下您的代码:

  • B=动物
  • A=母牛
更换后:

public class Program
{
    public static void main(String [] args) 
    { 
        Animal a = new Cow(); 
          a.sayMooo();//compiler complains at this line. You try to animal to say "moo"?
          a.speed(10);  
          a.speed(10.0); 
    } 
} 
    class Animal { 
        public void speed(int i) 
        { 
            System.out.println(i*2); 
        } 
    }

    class Cow  extends Animal{ 
        public void p(int i) 
        { 
            System.out.println(i); 
        } 
        public void sayMooo(){

        }
    } 
并非所有动物都是牛

当然

并非所有动物都说“哞哞”

但是


所有的牛都是动物

无法理解您的答案。什么是虚拟方法和vTable?如果可能,请详细说明。无法理解您的答案。什么是虚拟方法和vTable?如果可能,请详细说明。请说明否决投票的原因。请看我非常简单的答案,可以帮助您进行排序请看我简单的答案,它可以帮助你解决问题