Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么动态类型方法不可见?_Java - Fatal编程技术网

Java 为什么动态类型方法不可见?

Java 为什么动态类型方法不可见?,java,Java,我们可以说: interface A{ void foo(); } class B implements A{ void foo(){} void doNothing(){} } 我创建了一个B实例 A object=new B(); 为什么在object.doNothing()调用时出现编译错误?因为类型a没有\doNothing方法,变量object具有编译时类型A,因为object是A,在类A中,没有任何名为doNothing的函数,您的代码通过A的外部接口

我们可以说:

interface A{
    void foo();
}

class B implements A{
    void foo(){}
    void doNothing(){}
}
我创建了一个B实例

 A object=new B();

为什么在object.doNothing()调用时出现编译错误?

因为类型
a
没有
\doNothing
方法,变量
object
具有编译时类型
A
,因为
object
A
,在
类A
中,没有任何名为
doNothing
的函数,您的代码通过
A
的外部接口查看
对象,而as
A
没有方法
doNothing
会出现编译错误。

因为在编译时,编译器会检查引用类型方法绑定。因此方法
doNothing()
在接口
A


在编译时,编译器无法确定这些引用中对方法
doNothing()
的调用是否实际引用了该方法的哪个版本-超类版本还是子类版本。

因为对象是A,而A没有名为doNothing的方法。如果要执行doNothing方法,请将其添加到接口A:

interface A {
    void foo();
    void doNothing();
}
或者将对象创建为B而不是A

B object = new B();
您正在使用“多态性”。这是将对象用作其父对象时的技术。 假设此实现:

public interface Animal {
    public void go();
}

class Dog implements Animal {
    public void go() {
        walk();
    }
}
class Fish implements Animal {
    public void go() {
        swim();
    }
}
class Duck implements Animal {
    public void go() {
        fly();
    }
}
现在,您可以执行以下操作:

Animal[] animals = {new Dog(), new Fish(), new Duck()};
现在,只要想让动物离开,就可以简单地调用
go()首选数组元素作为动物的方法(不必担心它们的移动类型)


现在,你能让一条鱼走路吗?不,因为不是所有的动物都会走路。
这就是为什么不能在父对象上调用子对象的方法,因为父对象看到的子对象是相同的,它只知道如何去不走,等等


在您的问题中,
A
接口只知道
void foo()方法,不知道
void doNothing()方法。

加一;公平的问题。该语言就是这样设计的,因此您可以获得编译时类型检查的好处(例如程序稳定性)。其他语言(如VBA)比这更容易出错。如果您知道或甚至怀疑
对象
B
,则可以尝试强制转换,然后可以访问
执行任何操作