Hi Martin, It's because static methods are not inherited, and therefore cannot be overridden. If I remember correctly, this is mentioned in the Java Language Specification -- but I'm too lazy to verify that. Hope this helps. Good Luck, Avi.
Dirk Schreckmann
Sheriff
Joined: Dec 10, 2001
Posts: 7023
posted
0
Static methods are inherited by a subclass. Static methods do not participate in polymorphism - there is no overriding a static method (though they can be "shadowed" by a subclass). Since, they cannot be overridden, what would it mean to have one that were abstract? It would seem to be a contradiction. Also, static methods belong to a class - not to instances of a class. How could a class be polymorphic and allow for overriding of its behaviors? I'm not sure I can make sense out of such a notion. Are you getting the idea, Martin?
Static cannot be overridden Abstract requires overriding
JavaBeginnersFaq "Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
Ilja Preuss
author
Sheriff
Joined: Jul 11, 2001
Posts: 14112
posted
0
Originally posted by Dirk Schreckmann: Also, static methods belong to a class - not to instances of a class. How could a class be polymorphic and allow for overriding of its behaviors?
For that, a class needed to be an object - as in Smalltalk, for example.
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
Martin Smith
Greenhorn
Joined: Apr 05, 2003
Posts: 22
posted
0
Dirk, You say you cannot override a static method (but instead it is hidden), compile this;
note the compiler error - "m() in b cannot override m() in a; attempting to use incompatible return" The java compiler appears to think it is overriding.
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
Hi Martin, Read Dirk's post closer :
... there is no overriding a static method (though they can be "shadowed" by a subclass) ...
You can shadow a static method in a subclass, but you really don't override it because the mechanism for accessing static methods is thru the class identifier:
You really don't override the method since you must know the class and not just some reference to an instance of one of the ancestors of the class to access the method. As Ilja pointed out, you would need a meta-class type for classes to be polymorphic and Java doesn't have that. Michael Morris
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Thomas Paul
mister krabs
Ranch Hand
Joined: May 05, 2000
Posts: 13974
posted
0
Static methods do not participate in polymorphism. Overriding always involves polymorphism. Therefore static methods can not be overridden. This whole situation would be much simpler if Java had gone the way of C# and forced you to run static methods with the class identifier instead of allowing you to use an instance variable.
sorry I should have posted on the beginner's forum... I get that a static method is to do with the Class not the instance and so polymorphism/overriding etc don't apply. So why does it not allow the method in the child to have a different return type? The compiler "knows" what it's going at compile time. Is it just the rule that a "shadowed" method has to match the full signiture in the same way an overridden one does?
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18652
posted
0
The java compiler appears to think it is overriding. Yes, that particular error message was written by someone who didn't understand the JLS. The behavior of the compiler is correct (the code should not compile), but the reason it gives is incorrect (this has nothing to do with overriding). I guess Sun's been too busy to correct this, and as long as the behavior is correct... So why does it not allow the method in the child to have a different return type? The compiler "knows" what it's going at compile time. Is it just the rule that a "shadowed" method has to match the full signiture in the same way an overridden one does? Fundamentally, I don't think there's really any good reason for this. I believe they do it to keep things simpler for people trying to understand the class - given that many people do mix up shadowing and overriding behavior, this rule reduces the differences between them - which cuts down on the number of unexpected side effects, for people who use the class without fully understanding it. Seems rather silly to me though. [ April 06, 2003: Message edited by: Jim Yingst ]
"I'm not back." - Bill Harding, Twister
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
Fundamentally, I don't think there's really any good reason for this. I believe they do it to keep things simpler for people trying to understand the class -
I agree with Jim that from a purely semantic point of view, it should be allowed. The reason though probably has to do more with compiler implementation issues such as using the same lexical analysis for class methods as are used for instance methods. In other words, the lazy reuse of working code. But that's just a guess, so don't take it to the bank. Michael Morris
Thomas Paul
mister krabs
Ranch Hand
Joined: May 05, 2000
Posts: 13974
posted
0
First off, static methods are hidden and not shadowed. There is a difference between the two. Shadowed entities are in scope in the class. For example when we use a constructor parameter with the same name as an instance variable, the parameter is said to shadow the instance variable even though both are in scope. (The instance variable can be accessed with this.var) Hidden entities are never in scope in the subclass. The only way to access them is by the class name (static) or "super" (non-static). As to the question as to why you can't use the same method name with a different return type... how would the compiler know which one you were trying to use? Remember, that non-hidden methods are inherited therefore unless you match the entire signature (the same rule for overriding) the compiler has the potential problem of not knowing which method you want to run. For example, if method1 was hidden and returned an int in the parent class and a double in the child class, how would the compiler know which you wanted if you did this: method1(); // ignoring the return value. [ April 07, 2003: Message edited by: Thomas Paul ] [ April 07, 2003: Message edited by: Thomas Paul ]
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
As to the question as to why you can't use the same method name with a different return type... how would the compiler know which one you were trying to use?
If the methods are static and presumably will be accessed thru the declaring class why does the compiler need to know? You wouldn't be able to access the overridden method thru any ancestor of a subclass that changed the signature but, once again, it is a class method, not polymorphic. The only real problem I see is if the method were called internally by an instance method without referring to the class. Even that could be handled with a compiler equipped to do check the semantics of class methods. Michael Morris
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18652
posted
0
Tom - good catch on hidden vs. shadowed; I overlooked that. Not sure I agree with your use of "in scope", but there are differences in how you access a hidden method vs. a shadowed one. Will check the terminology more closely. As to the question as to why you can't use the same method name with a different return type... how would the compiler know which one you were trying to use? The same way it does now - by searching for a method with the same name and parameter types as the one mentioned in the code. (And starting the search in the class corresponding to the declared type in the code, and moving up to successively search each superclass until a match is found. Return type is not considered at all, until after the matching method has been unambiguously determined. At that point the compiler looks at the return type and either determines that it's OK, or it throws an error - it doesn't look to see if another method provides a better fit. Remember, that non-hidden methods are inherited therefore unless you match the entire signature (the same rule for overriding) the compiler has the potential problem of not knowing which method you want to run. Return type is not part of the signature. [ April 07, 2003: Message edited by: Jim Yingst ]
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
Return type is not part of the signature.
Absolutely right. That's an easily forgotten fact. It seems unnatural that return type is not part of the signature.
Thomas Paul
mister krabs
Ranch Hand
Joined: May 05, 2000
Posts: 13974
posted
0
return type is not part of the signature but an overriding and hiding method must have the exact same signature plus the same return type (I have seen this called the full signature in some books). I see your point about static methods. Since they aren't polymorphic there should be no reason that the hiding method can't have a different return type. A similar problem exists with the throws clause having to follow the override rules. I went through the bug database and there is a mention (Bug ID: 4630147) of the throws issue with a comment on "binary compatibility" (which I don't think applies here) and a note that it may be examined for JLS 3.