Here's a simple example to illustrate. Imagine that PersonOverwritten
looked like this:
public class PersonOverwritten extends Person {
public PersonOverwritten(String nome, int idade) {
super();
}
public void pickupSticks() {}
}
Very clearly you would not be able to do
Person superPerson = new Person("marc", 18);
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
subPerson.pickupSticks();
because the object assigned to subPerson
does not have the pickupSticks
method.
The reason that the compiler allows you to write code like that, though, is that you might one day want to do something like this:
Person person = new PersonOverwritten("marc", 18);
((PersonOverwritten)person).pickupSticks();
In this case, there will of course not be a runtime error, because the object that you have assigned to person
does support the extended interface. A very common place to see something like that was before generics were introduced in Java 1.5, and all the collections returned Object
when you accessed them.
Update
To elaborate a bit, Java uses types to determine the contract that an object fulfills, rather than a direct inspection of the attributes. It does not use duck-typing, like say Python. The compiler will allow you to cast Person
to PersonOverwritten
because it might be possible. The runtime will forbid you from using an actual Person
object as a PersonOverwritten
because, according to Java, it does not fulfill the interface.