I have two little questions about Java. You can find the source code I used to test things here.
1) Say, you have a Person class and a subclass of Person, Student. The Person class contains a method printInfo() that prints the name and the age of the person on standard output. The Student subclass overrides the method printInfo(), calls super.printInfo() and prints the percentage of the student as well.
You create the variable s as follows:
Dynamic binding makes it so that the implemention of printInfo() of the Student class is used. Is there still a way to call the implementation of the Person class? Downcasting doesn't work.
2) You make an interface MyInterface, which contains the method printInfo(), have the Person class implement it, and create a new person:
I thought the callable methods of t were limited to the methods defined in MyInterface, if you declare the variable like this. Why can wait(), notify(), toString() still be used?
i think the answer to 1) is that you can't. i'm not entirely certain, though, so i'll defer to the java experts here for that.
on 2), the answer is also no, they aren't limited to that. implementing an interface only says you promise to implement at least those methods specified in the interface, it doesn't say anything about any other methods; any ones you declare "public" can still be accessed, whether or not they're mentioned in the interface.
Joined: Jun 11, 2005
About 2: try it, add the method
to the Person class, and DON'T add it to MyInterface. Then declare your variable like this (MyInterface as the type, not Person):
1) M Beck is right - you can't. You will need to change your design if you need to do that.
2) That's caused by a somewhat questionable language design. The Java language works as if there was a super interface that all interfaces and the Object class inherit from, which declares all the methods the Object class implements. Unfortunately, that interface doesn't really exist, the compiler just behaves as if it would exist...
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Joined: Jan 14, 2005
my apologies for misreading your question #2; i wasn't paying sufficient attention. you're right, if you declare the variable ("t") as being of the interface type ("MyInterface") instead of the object type ("Person"), then you get the phenomenon Ilja described. in that particular case, only the methods declared in the interface are accessible (since that's what the type of the variable is declared as), with the caveat that a few methods from the class "Object" are implicitly declared in every Interface.
incidentally, i agree with Ilja that this is weird language design; it should have been made specific somehow. as it is, these methods seem to appear "by magic", and you have to dig deep in the language specification to find out why. but it's hardly the only design flaw in Java, so...
the key to keeping all this straight is your reasons for choosing the type of the variable "t", and your reasons for implementing "MyInterface" in the class "Person". is it more important that "t" be limited to only a specific interface, or that more specific methods be accessible through it? is "Person" more a specific instance of the interface, or of something else — is the interface more important than what's in Person and its superclass, or vice versa?
sometimes the interface is more important, and the variables should properly be typed to the interface instead of the class — the Collections API is a good example. you shouldn't have variables of type HashMap, but of type Map, because the interface matters more in that case. but other times it's the other way around, and the interface matters hardly at all — all the marker interfaces are great examples. having a variable of type Serializable almost never makes much sense. it all depends on your design.