Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't hiding of virtual functions/methods allowed in Java and 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;
}

without virtual it's working fine, But When I changed A's function to virtual then It's saying return type should be same why?

I tried same thing in 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 also showing error when I tried different return type in sub-class. ( I think because by default all instance methods are virtual by default) I was expecting int k() should hide void k() and int k() should invoke from Y's object.

So I think it's problem with virtual. Why child class should be use same return type when function declared as virtual?

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

Example:

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.
    }
}

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

like image 851
Asif Mushtaq Avatar asked Jan 07 '23 11:01

Asif Mushtaq


1 Answers

You guessed correctly, "polymorphic" is the key word :) Polymorphism means that, if Y is a subclass of X, then Y effectively is X, and can be used as X anywhere.

Now, that means, if X has a method void k(), then Y must also have the same method (otherwise, you would not be able to use it as X). But you cannot have two different methods with the same signature, and therefore Y.k() must also return void (otherwise, it would be a different method).

In C++ case, non-virtual functions aren't polymorphic: A.k and B.k are two completely different methods in that case, and therefore there is no restriction.

To put it simply, let's change your example a little bit: suppose, that you defined X.k to return int, and Y.k() as void. Imagine a function like this:

     int plusOne(X x) {
        return x.k() + 1
     }

This should compile and work, right? But what about plusOne(new Y())? This must also work, because Y is X ... but, if it was possible for Y.k() to return a void, what would plusOne do with it?

like image 68
Dima Avatar answered Feb 11 '23 09:02

Dima