I have a small doubt regarding method overriding.
Animal animal = new Dog();
animal.makeSound();
Dog is the child class of Animal. animal.makeSound()
will call dog object makeSound()
because it's late binding. When we don't override dog
it will call animal class makeSound()
. But let's take this code.
Dog dog = new Dog();
dog.makeSound();
If the dog doesn't override the parent method, still it has parent method, which is normal in the case of inheritance. I just wondering about the internal implementation. Does the dog internally override the parent method and call super inside it like this?
@Override
public void makeSound() {
super.makeSound();
}
Thank you.
CodePudding user response:
No. And you can use javap
(the decompiler tool which shows you bytecode) to check this. The dog class does not have a makeSound
method at all.
The compiler sees the characters "dog.makeSound()" and knows what Animal.class and Dog.class look like - either because those are on the classpath, or those are in the same compilation run. The compiler itself therefore 'resolves' what you mean with this. If either Dog or Animal is missing, the compiler will error out, telling you that you're missing a required class, and call it a day - no class file, making the rest moot.
In the class file format, method calls are fully specced. Their identity is based on a fully qualified class name and the method name and the exact types (without generics) of all parameters and the return type. Only if all that is identical does the JVM consider it the same method. As far as the JVM is considered, the method in java code "foo".toLowerCase()
is named: "java/lang/String::toLowerCase::()Ljava/lang/String;". A mouthful, fortunately, we program in java, and not in bytecode.
Thus, at the class level, your "dog.makeSound();"
is compiled to something along the lines of:
INVOKEVIRTUAL com.foo.User214534sPackage.Animal :: makeSound :: ()V
and the JVM, when it sees this, checks what's top of stack (as this is an instance method, the 'receiver' (the dog.
part) is effectively the first parameter), checks what the actual type is of the object that the variable is pointing at, figures out that it is com.foo.User214534sPackage.domestics.Dog
, and checks if said class has a makeSound
method defined. If it does, the JVM will actually invoke that (even though the INVOKEVIRTUAL call mentions only Animal.makeSound). If it does not, it'll check the parent type of Dog.. and will keep doing that until it gets to Animal which of course has a makeSound method (if it didn't, javac
could not have produced the class file).