有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

为什么爪哇和C++中不允许隐藏虚拟函数/方法?

#include <iostream>
class A{
    public:
        void k(){
            std::cout << "k from A";
        }
};
class B:public A{
    public:
        int k(){
            std::cout << "k from B"; 
            return 0;
        }
};
int main(){
    B obj;
    obj.k();

    return 0;
}

没有virtual,它工作得很好,但是当我把A的函数改为virtual时,它说返回类型应该是相同的,为什么

我在Java中尝试了同样的方法:

class X{
    public void k(){
        System.out.println("k From X");
    }
}
public class Y{
    public int k(){
        System.out.println("k From Y");
        return 0;
    }
}

当我在子类中尝试不同的返回类型时,Java也显示了错误。(我认为因为默认情况下所有实例方法都是虚拟的)我希望int k()应该隐藏void k(),并且int k()应该从Y的对象调用

所以我认为这是虚拟现实的问题。当函数声明为虚拟时,为什么子类应该使用相同的返回类型

如果是多态性行为问题。然后我认为对象足以决定函数调用

例如:

class X{
    public void k(){
        System.out.println("k From X");
    }
}
public class Y extends X{
    public int k(){
        System.out.println("k From Y");
        return 0;
    }
    public static void main(String[] args){
        X obj=new Y();
        obj.k(); // object Y found now just call k() from Y.
    }
}

为什么我们不能在子类或子类中更改返回类型


共 (2) 个答案

  1. # 1 楼答案

    If it polymorphic behavior problem. Then I think object is enough to determined the function calling

    动态多态性发生在运行时,但返回值的类型在编译时确定

    why we can't change return type in sub-class or child class?

    考虑下面的例子(为了便于解释,我对示例代码中的返回类型做了一些修改)

    class A{
        public:
            virtual int k(){  // returns int
                std::cout << "k from A";
                return 0;
            }
    };
    class B:public A{
        public:
            std::string k(){  // returns std::string
                std::cout << "k from B";
                return std::string();
            }
    };
    int main(){
        A* pa = new B;
        int r = pa->k(); // r is supposed to be int, the type is deduced at compile time
    
        delete pa;
        return 0;
    }
    

    通过基类指针(或引用)调用虚拟函数f(),应该返回一个int,但根据动态分派的结果,实际上会调用B::k(),但它将返回一个完全不同的类型(即std::string)。这是矛盾的,也是不合理的

    从C++标准中,$103/7虚函数[Copy.Virtual]

    The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions.

  2. # 2 楼答案

    我不知道你为什么在我已经gave you the answer here的时候再次发布这个问题。但这里是正确的答案

    java方法和C++虚函数可以被忽略,但是不同的返回类型在重写时允许,只要它们是兼容eEM>。只有冲突的返回类型才是不允许的。例如,在C++中:

    struct Base {
        virtual Base* f() { return nullptr; }
    };
    
    struct Derived : Base {
        Derived* f() override { return nullptr; }
    };
    

    在Java中:

    class Base {
        Base f() { return null; }
    }
    
    class Derived extends Base {
        @Override
        Derived f() { return null; }
    }