Overloading and Overriding at the same time for a parent child class in java but it is not working and i can't figure out why

58 Views Asked by At

Okay so I made two classes parent and child , child extends parent they both have a function called print. Child class however have two print functions one is parameterized and other one is not (overloading print function in child class).

parent class has only one print function.

Now when i made a object like this

parent p = new child();

it is giving compile error but it should not and i dont know why ?

code snippet :


class temp {
    public static void main(String[] args) {
        try {
            parent p = new child();
            p.print();
            p.print(1);
        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }
    }
    
}

class parent {
    void print() {
        System.out.println("parent print function");
    }
}

class child extends parent {
    void print() {
        System.out.println("child print function");
    }

    void print(int i) {
        System.out.println("child parameterized print function");
    }
}

Now since child is inheriting parent both their contructors will be called but eventually the object that is being created is a child class object , so it should give no error while running print(1) since child has print(int i ) funciton, but it gives an error that parent class does not have print(int i) funciton.

Now for another scenario i add print(int i) function in the parent as well then everything works as expected parent class's function is overridden by child.

Also if i just add a print(int i) funciton in the parent only and remove it from the child then also this code works and it prints that parent function , that is also an expected behaviour.

this is the only case which seems to be giving an error , if someone could share some insight into this, that would be very helpful , thanks :).

2

There are 2 best solutions below

0
ControlAltDel On
parent p = new child();
p.print();
// Below method is only in child, meaning you cannot call 
// it on the parent variable without casting it to a child
p.print(1);
0
anqit On

This is because you declare your variable p to be of type parent:

parent p = new child(); Sure, you've assigned to p a value of type child, but the static type is still parent, and the compiler cannot make any assumptions beyond that. Say you made another sub-class of parent like this:

class StepChild extends parent {
    void print(String i) {
        System.out.println("step child parameterized print function");
    }
}

You could then assign a value of type StepChild to p:

p = new StepChild();

StepChild doesn't have a print method that takes an int, so calling p.print(1) in that case would be an error. If you want to be able to call a method that only belongs to a specific type, you need to tell the compiler that it is at least that type. In your case, you could do: child p = new child();. Now the compiler knows that p is actually a child, and cannot be assigned a value that doesn't have a print(int) method, so you can safely call print(1); Another, but less safe option, is to cast the variable to a more specific type:

((child) p).print(1);

Here, you are telling the compiler "trust me, I know that this is actually a child, not just a parent, so treat it as one and call print(1) on it." This is useful sometimes, but you need to be careful because if p is not actually a child when you cast it, it will throw a runtime error (ClassCastException to be exact). You are basically subverting the Java compiler's type safety mechanism at this point.

It's analogous to say, knowing you have a vehicle of some kind, but you don't know if it's a bicycle or a car. If you try to turn on the engine, but you have a bicycle, that will fail. However, you know that regardless of the specific type of vehicle you have, you can use it to transport yourself from one location to another. Some languages will let you try to turn on the engine without knowing the specific vehicle type and let you fail at runtime. Java does not let you do that (very easily, at least), and will only allow you to call the methods it knows for sure the receiving type has.