Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Inheritance_Polymorphism_Parent Child - Fatal编程技术网

Java 正在将子级转换为父级-由于缺少方法而导致编译时错误-为什么?

Java 正在将子级转换为父级-由于缺少方法而导致编译时错误-为什么?,java,oop,inheritance,polymorphism,parent-child,Java,Oop,Inheritance,Polymorphism,Parent Child,下面是一个将子类强制转换为父类,然后调用方法的简短示例 ((A) b).foo(1, 2, 3); //is equivalent to A b1 = new B(); b1.foo(1, 2, 3); 我希望foo方法在子类中调用,而不是在父类中调用。但是,我得到一个编译错误,说父类没有这个方法 ((A) b).foo(1, 2, 3); //is equivalent to A b1 = new B(); b1.foo(1, 2, 3); 如果我只在子类上调用它,为什么Java关心父

下面是一个将子类强制转换为父类,然后调用方法的简短示例

((A) b).foo(1, 2, 3); 
//is equivalent to
A b1 = new B();
b1.foo(1, 2, 3);
我希望foo方法在子类中调用,而不是在父类中调用。但是,我得到一个编译错误,说父类没有这个方法

((A) b).foo(1, 2, 3); 
//is equivalent to
A b1 = new B();
b1.foo(1, 2, 3);
如果我只在子类上调用它,为什么Java关心父类是否拥有它

public static void main(String[] args)
{
    A a = new A();
    B b = new B();

    b.foo(1, 2, 3); // Ok

    ((A) b).foo(1, 2); // Also ok. 
                       // Prints "In foo(int, int) method of class B"

    ((A) b).foo(1, 2, 3); // Will not compile

}
//在代码的后面

class A 
{
    public int foo(int a, int b) 
    {
        System.out.println("In foo(int, int) method of class A");
        return 1;
    }
}

class B extends A 
{

    public int foo(int a, int b) 
    {
        System.out.println("In foo(int, int) method of class B");
        return 0;
    }
    public int foo(int a, int b, int c) 
    {
        System.out.println("In foo(int, int, int) method of class B");
        return -1;
    }
}
((A)b)
被视为
A
,尽管它是
foo(int,int)
b

这意味着,因为
((A)b)
被称为
A
,所以只能调用
A
具有的方法


A
只有
foo(int,int)
,因此不能调用
foo(int,int,int)

您面临的问题与方法重载的概念有关

foo(inta,intb,intc)
不是
a
中的方法。尽管您定义的所有方法都具有相同的名称,但它们被视为单独的方法,因为它们各自具有不同数量的参数

当您尝试调用
((A)b).foo(1,2,3)
时,
b
被视为
A
的实例。Java试图在
a
中找到一个名为
foo
的方法,该方法有三个参数,但找不到,因为它不存在

((A) b).foo(1, 2, 3);
上述代码可以可视化为:

A a = (A)b;
a.foo(1, 2, 3);
正如您所看到的,这里的引用变量是类型“A”,所有方法名称解析都应该基于类型“A”。具有三个参数(重载方法)的foo(…)在A中不存在,因此它会抛出一个错误。

((A)b)
之所以有效,是因为A的方法foo具有匹配的签名,但它执行B的foo,因为在运行时jvm可以理解它正在使用B的实例。这在另一个方法中不可用

((A) b).foo(1, 2, 3); 
//is equivalent to
A b1 = new B();
b1.foo(1, 2, 3);

Java是静态类型的,在编译器看来,您正试图调用类型a和类型B上不存在的方法。编译器不知道运行时类型是什么。

谢谢。但是如果我们这样想,为什么my((A)b).foo(1,2)调用b的方法而不是A的方法?方法解析基于引用变量。这在编译时发生。你可以参考这个链接。但是要调用的实际方法是在运行时根据实例化的实际对象决定的。因此,在您的示例中,该方法是在B的对象上调用的。谢谢。这是有道理的。接下来的一个问题是:JVM如何在运行时判断b实际上是b的实例,而编译器不是?我可能应该去查一个关于这个的线程……编译器根据它能看到的东西工作,它不能假设运行时类型是什么。例如,您可以将B对象作为参数传递给需要a的方法,或者将B存储在a的列表中。不确定这是否有帮助,但请查看