Animal is a superclass of Dog and Dog has a method called bark
public void bark()
{
System.out.println("woof");
}
Consider the following:
Animal a = new Dog();
if (a instanceof Dog){
a.bark();
}
What will happen?
- the assignment isn't allowed
- the call to bark is allowed and "woof" is printed at run time
- the call to bark is allowed but nothing is printed
- the call to bark causes a compile time error
- the call to bark results in a run time error
I said 2 as we are checking if the object is a dog; as dog is the class with the bark method in it, if it is then we call it which will print out :s
Is my understanding correct here?
Your rationale is correct, but that's not the way it works.
Java is an static typed language that means, the validity of the methods an object may respond to is verified at compile time.
You may think the check:
Would do, but actually it doesn't. What the compiler do is check against the "interface" of the declared type ( Animal in this case ). The "interface" is composed of the methods declared on the Animal class.
If the bark() method is not defined in the super class Animal the compiler says: "Hey, that won't work".
This is helpful, because "sometimes" we make typos while coding ( typing barck() instead for instance )
If the compiler doesn't not warn us about this, you would have to find it at "runtime" and not always with a clear message ( for instance javascript in IE says something like "unexpected object" )
Still, static typed language like java allow us to force the call. In this case it is using the "cast" operator ()
Like this
In line 3 your are "casting" to a Dog type so the compiler may check if bark is a valid message.
This is an instruction to to compiler saying "Hey I'm the programmer here, I know what I'm doing". And the compiler, checks, Ok, dog, can receive the message bark(), proceed. Yet, if in runtime the animal is not a dog, a runtime exception will raise.
The cast could also be abbreviated like:
That will run.
So, the correct answer is 4: "the call to bark causes a compile time error"
I hope this helps.
It's 4. You can't ask a generic Animal - which is what your code says a is - to bark. Because you could just as easily have said
and the bark line doesn't have a way to know that you didn't.
The key is in the following line:
Although a new instance of
Dog
was created, its reference is bya
which is declared to be of the typeAnimal
. Therefore, any references toa
makes thenew Dog
be handled as anAnimal
.Therefore, unless
Animal
has abark
method, the following line will cause a compiler error:Even though
a
is tested to see if it is an instance ofDog
, anda instanceof Dog
will actually returntrue
, the variablea
is still of is of typeAnimal
, so the block inside theif
statement still handlesa
as anAnimal
.This is a feature of statically-typed languages where variables are assigned a type ahead of time, and checked at compile-time to see that the types match. If this code were performed on a dynamically-typed language, where the types are checked at runtime, something like the following could be allowed:
a.bark()
is guaranteed only to execute when the instance is aDog
, so the call tobark
will always work. However, Java is a statically-typed language, so this type of code is not allowed.