Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the declared type of an object matter at runtime?

Tags:

java

types

oop

In a statically-typed language like Java, from what I've learned, type declaration is essentially for compile-time catching of errors, an obvious advantage over dynamically typed languages. But looking at the times when Java does late binding, we get errors like ClassCastException, showing how the declared types are relevant somehow at runtime. But why does the declared type actually matter?

For example:

public class TestClass 
{
   public static void main(String[] args) 
   {
       Animal d = new Animal();
      ((Dog)d).bark(); //ClassCastException because an Animal is not a dog, which would make sense to throw at compile-time, but not at runtime.
   }
}

class Dog extends Animal{}

class Animal
{
   void bark()
   {
       System.out.println("Woof");
   }
}

I know this is a super bad example because it's an unnessesary cast, but I'm just giving an example of it. We try to avoid runtime exceptions at all times, so why can't Java disregard the cast and call method bark on the actual object type, which in this case is Animal? I've been reading about duck typing and it seems like a similar adaption of this could work in Java (i.e. if this object woofs, then let's treat it like a dog!) or any statically-typed language, because at runtime, Java seems to act dynamically.

Edit: Now that I'm thinking about it more, this question is about the need for runtime type checking. Why does it need to happen? It seems bad that static typed languages halt with a runtime exception on a cast which could be ignored.

like image 227
rb612 Avatar asked Jan 07 '23 22:01

rb612


1 Answers

why can't Java disregard the cast and call method bark on the actual object type, which in this case is Animal?

That would be semantically wrong thing to do. What if Dog and Amimal has different versions of Bark method?

Let's say you have a non virtual method Bark in your base class. When you call Bark on Dog it should call Dog.Bark; similarly when you call Bark on Animal it should call Animal.Bark.

If the compiler disregards the cast as you said, it would end up calling the wrong method.

Note that in C# by default all methods are non virtual as opposed to java. So this argument makes more sense in the context of C#.

like image 91
Sriram Sakthivel Avatar answered Jan 12 '23 00:01

Sriram Sakthivel