Related
Why is it not possible to override static methods?
If possible, please use an example.
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.
Personally I think this is a flaw in the design of Java. Yes, yes, I understand that non-static methods are attached to an instance while static methods are attached to a class, etc etc. Still, consider the following code:
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(getBonusMultiplier());
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
This code will not work as you might expect. Namely, SpecialEmployee's get a 2% bonus just like regular employees. But if you remove the "static"s, then SpecialEmployee's get a 3% bonus.
(Admittedly, this example is poor coding style in that in real life you would likely want the bonus multiplier to be in a database somewhere rather than hard-coded. But that's just because I didn't want to bog down the example with a lot of code irrelevant to the point.)
It seems quite plausible to me that you might want to make getBonusMultiplier static. Perhaps you want to be able to display the bonus multiplier for all the categories of employees, without needing to have an instance of an employee in each category. What would be the point of searching for such example instances? What if we are creating a new category of employee and don't have any employees assigned to it yet? This is quite logically a static function.
But it doesn't work.
And yes, yes, I can think of any number of ways to rewrite the above code to make it work. My point is not that it creates an unsolvable problem, but that it creates a trap for the unwary programmer, because the language does not behave as I think a reasonable person would expect.
Perhaps if I tried to write a compiler for an OOP language, I would quickly see why implementing it so that static functions can be overriden would be difficult or impossible.
Or perhaps there is some good reason why Java behaves this way. Can anyone point out an advantage to this behavior, some category of problem that is made easier by this? I mean, don't just point me to the Java language spec and say "see, this is documented how it behaves". I know that. But is there a good reason why it SHOULD behave this way? (Besides the obvious "making it work right was too hard"...)
Update
#VicKirk: If you mean that this is "bad design" because it doesn't fit how Java handles statics, my reply is, "Well, duh, of course." As I said in my original post, it doesn't work. But if you mean that it is bad design in the sense that there would be something fundamentally wrong with a language where this worked, i.e. where statics could be overridden just like virtual functions, that this would somehow introduce an ambiguity or it would be impossible to implement efficiently or some such, I reply, "Why? What's wrong with the concept?"
I think the example I give is a very natural thing to want to do. I have a class that has a function that does not depend on any instance data, and which I might very reasonably want to call independent of an instance, as well as wanting to call from within an instance method. Why should this not work? I've run into this situation a fair number of times over the years. In practice I get around it by making the function virtual, and then creating a static method whose only purpose in life is to be a static method that passes the call on to the virtual method with a dummy instance. That seems like a very roundabout way to get there.
The short answer is: it is entirely possible, but Java doesn't do it.
Here is some code which illustrates the current state of affairs in Java:
File Base.java:
package sp.trial;
public class Base {
static void printValue() {
System.out.println(" Called static Base method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Base method.");
}
void nonLocalIndirectStatMethod() {
System.out.println(" Non-static calls overridden(?) static:");
System.out.print(" ");
this.printValue();
}
}
File Child.java:
package sp.trial;
public class Child extends Base {
static void printValue() {
System.out.println(" Called static Child method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Child method.");
}
void localIndirectStatMethod() {
System.out.println(" Non-static calls own static:");
System.out.print(" ");
printValue();
}
public static void main(String[] args) {
System.out.println("Object: static type Base; runtime type Child:");
Base base = new Child();
base.printValue();
base.nonStatPrintValue();
System.out.println("Object: static type Child; runtime type Child:");
Child child = new Child();
child.printValue();
child.nonStatPrintValue();
System.out.println("Class: Child static call:");
Child.printValue();
System.out.println("Class: Base static call:");
Base.printValue();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Child:");
child.localIndirectStatMethod();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Base:");
child.nonLocalIndirectStatMethod();
}
}
If you run this (I did it on a Mac, from Eclipse, using Java 1.6) you get:
Object: static type Base; runtime type Child.
Called static Base method.
Called non-static Child method.
Object: static type Child; runtime type Child.
Called static Child method.
Called non-static Child method.
Class: Child static call.
Called static Child method.
Class: Base static call.
Called static Base method.
Object: static/runtime type Child -- call static from non-static method of Child.
Non-static calls own static.
Called static Child method.
Object: static/runtime type Child -- call static from non-static method of Base.
Non-static calls overridden(?) static.
Called static Base method.
Here, the only cases which might be a surprise (and which the question is about) appear to be the first case:
"The run-time type is not used to determine which static methods are called, even when called with an object instance (obj.staticMethod())."
and the last case:
"When calling a static method from within an object method of a class, the static method chosen is the one accessible from the class itself and not from the class defining the run-time type of the object."
Calling with an object instance
The static call is resolved at compile-time, whereas a non-static method call is resolved at run-time. Notice that although static methods are inherited (from parent) they are not overridden (by child). This could be a surprise if you expected otherwise.
Calling from within an object method
Object method calls are resolved using the run-time type, but static (class) method calls are resolved using the compile-time (declared) type.
Changing the rules
To change these rules, so that the last call in the example called Child.printValue(), static calls would have to be provided with a type at run-time, rather than the compiler resolving the call at compile-time with the declared class of the object (or context). Static calls could then use the (dynamic) type hierarchy to resolve the call, just as object method calls do today.
This would easily be doable (if we changed Java :-O), and is not at all unreasonable, however, it has some interesting considerations.
The main consideration is that we need to decide which static method calls should do this.
At the moment, Java has this "quirk" in the language whereby obj.staticMethod() calls are replaced by ObjectClass.staticMethod() calls (normally with a warning). [Note: ObjectClass is the compile-time type of obj.] These would be good candidates for overriding in this way, taking the run-time type of obj.
If we did it would make method bodies harder to read: static calls in a parent class could potentially be dynamically "re-routed". To avoid this we would have to call the static method with a class name -- and this makes the calls more obviously resolved with the compile-time type hierarchy (as now).
The other ways of invoking a static method are more tricky: this.staticMethod() should mean the same as obj.staticMethod(), taking the run-time type of this. However, this might cause some headaches with existing programs, which call (apparently local) static methods without decoration (which is arguably equivalent to this.method()).
So what about unadorned calls staticMethod()? I suggest they do the same as today, and use the local class context to decide what to do. Otherwise great confusion would ensue. Of course it means that method() would mean this.method() if method was a non-static method, and ThisClass.method() if method were a static method. This is another source of confusion.
Other considerations
If we changed this behaviour (and made static calls potentially dynamically non-local), we would probably want to revisit the meaning of final, private and protected as qualifiers on static methods of a class. We would then all have to get used to the fact that private static and public final methods are not overridden, and can therefore be safely resolved at compile-time, and are "safe" to read as local references.
Actually we were wrong.
Despite Java doesn't allow you to override static methods by default, if you look thoroughly through documentation of Class and Method classes in Java, you can still find a way to emulate static methods overriding by following workaround:
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
class RegularEmployee {
private BigDecimal salary = BigDecimal.ONE;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(this.getBonusMultiplier());
}
public BigDecimal calculateOverridenBonus() {
try {
// System.out.println(this.getClass().getDeclaredMethod(
// "getBonusMultiplier").toString());
try {
return salary.multiply((BigDecimal) this.getClass()
.getDeclaredMethod("getBonusMultiplier").invoke(this));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
// ... presumably lots of other code ...
}
final class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
public class StaticTestCoolMain {
static public void main(String[] args) {
RegularEmployee Alan = new RegularEmployee();
System.out.println(Alan.calculateBonus());
System.out.println(Alan.calculateOverridenBonus());
SpecialEmployee Bob = new SpecialEmployee();
System.out.println(Bob.calculateBonus());
System.out.println(Bob.calculateOverridenBonus());
}
}
Resulting output:
0.02
0.02
0.02
0.03
what we were trying to achieve :)
Even if we declare third variable Carl as RegularEmployee and assign to it instance of SpecialEmployee, we will still have call of RegularEmployee method in first case and call of SpecialEmployee method in second case
RegularEmployee Carl = new SpecialEmployee();
System.out.println(Carl.calculateBonus());
System.out.println(Carl.calculateOverridenBonus());
just look at output console:
0.02
0.03
;)
Static methods are treated as global by the JVM, there are not bound to an object instance at all.
It could conceptually be possible if you could call static methods from class objects (like in languages like Smalltalk) but it's not the case in Java.
EDIT
You can overload static method, that's ok. But you can not override a static method, because class are no first-class object. You can use reflection to get the class of an object at run-time, but the object that you get does not parallel the class hierarchy.
class MyClass { ... }
class MySubClass extends MyClass { ... }
MyClass obj1 = new MyClass();
MySubClass obj2 = new MySubClass();
ob2 instanceof MyClass --> true
Class clazz1 = obj1.getClass();
Class clazz2 = obj2.getClass();
clazz2 instanceof clazz1 --> false
You can reflect over the classes, but it stops there. You don't invoke a static method by using clazz1.staticMethod(), but using MyClass.staticMethod(). A static method is not bound to an object and there is hence no notion of this nor super in a static method. A static method is a global function; as a consequence there is also no notion of polymorphism and, therefore, method overriding makes no sense.
But this could be possible if MyClass was an object at run-time on which you invoke a method, as in Smalltalk (or maybe JRuby as one comment suggest, but I know nothing of JRuby).
Oh yeah... one more thing. You can invoke a static method through an object obj1.staticMethod() but that really syntactic sugar for MyClass.staticMethod() and should be avoided. It usually raises a warning in modern IDE. I don't know why they ever allowed this shortcut.
Method overriding is made possible by dynamic dispatching, meaning that the declared type of an object doesn't determine its behavior, but rather its runtime type:
Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"
Even though both lassie and kermit are declared as objects of type Animal, their behavior (method .speak()) varies because dynamic dispatching will only bind the method call .speak() to an implementation at run time - not at compile time.
Now, here's where the static keyword starts to make sense: the word "static" is an antonym for "dynamic". So the reason why you can't override static methods is because there is no dynamic dispatching on static members - because static literally means "not dynamic". If they dispatched dynamically (and thus could be overriden) the static keyword just wouldn't make sense anymore.
Yes. Practically Java allows overriding static method, and No theoretically if you Override a static method in Java then it will compile and run smoothly but it will lose Polymorphism which is the basic property of Java. You will Read Everywhere that it is not possible to try yourself compiling and running. you will get your answer. e.g. If you Have Class Animal and a static method eat() and you Override that static method in its Subclass lets called it Dog. Then when wherever you Assign a Dog object to an Animal Reference and call eat() according to Java Dog's eat() should have been called but in static Overriding Animals' eat() will Be Called.
class Animal {
public static void eat() {
System.out.println("Animal Eating");
}
}
class Dog extends Animal{
public static void eat() {
System.out.println("Dog Eating");
}
}
class Test {
public static void main(String args[]) {
Animal obj= new Dog();//Dog object in animal
obj.eat(); //should call dog's eat but it didn't
}
}
Output Animal Eating
According to Polymorphism Principle of Java, the Output Should be Dog Eating.
But the result was different because to support Polymorphism Java uses Late Binding that means methods are called only at the run-time but not in the case of static methods. In static methods compiler calls methods at the compile time rather than the run-time, so we get methods according to the reference and not according to the object a reference a containing that's why You can say Practically it supports static overring but theoretically, it doesn't.
In Java (and many OOP languages, but I cannot speak for all; and some do not have static at all) all methods have a fixed signature - the parameters and types. In a virtual method, the first parameter is implied: a reference to the object itself and when called from within the object, the compiler automatically adds this.
There is no difference for static methods - they still have a fixed signature. However, by declaring the method static you have explicitly stated that the compiler must not include the implied object parameter at the beginning of that signature. Therefore, any other code that calls this must must not attempt to put a reference to an object on the stack. If it did do that, then the method execution would not work since the parameters would be in the wrong place - shifted by one - on the stack.
Because of this difference between the two; virtual methods always have a reference to the context object (i.e. this) so then it is possible to reference anything within the heap that belong to that instance of the object. But with static methods, since there is no reference passed, that method cannot access any object variables and methods since the context is not known.
If you wish that Java would change the definition so that a object context is passed in for every method, static or virtual, then you would in essence have only virtual methods.
As someone asked in a comment to the op - what is your reason and purpose for wanting this feature?
I do not know Ruby much, as this was mentioned by the OP, I did some research. I see that in Ruby classes are really a special kind of object and one can create (even dynamically) new methods. Classes are full class objects in Ruby, they are not in Java. This is just something you will have to accept when working with Java (or C#). These are not dynamic languages, though C# is adding some forms of dynamic. In reality, Ruby does not have "static" methods as far as I could find - in that case these are methods on the singleton class object. You can then override this singleton with a new class and the methods in the previous class object will call those defined in the new class (correct?). So if you called a method in the context of the original class it still would only execute the original statics, but calling a method in the derived class, would call methods either from the parent or sub-class. Interesting and I can see some value in that. It takes a different thought pattern.
Since you are working in Java, you will need to adjust to that way of doing things. Why they did this? Well, probably to improve performance at the time based on the technology and understanding that was available. Computer languages are constantly evolving. Go back far enough and there is no such thing as OOP. In the future, there will be other new ideas.
EDIT: One other comment. Now that I see the differences and as I Java/C# developer myself, I can understand why the answers you get from Java developers may be confusing if you are coming from a language like Ruby. Java static methods are not the same as Ruby class methods. Java developers will have a hard time understanding this, as will conversely those who work mostly with a language like Ruby/Smalltalk. I can see how this would also be greatly confusing by the fact that Java also uses "class method" as another way to talk about static methods but this same term is used differently by Ruby. Java does not have Ruby style class methods (sorry); Ruby does not have Java style static methods which are really just old procedural style functions, as found in C.
By the way - thanks for the question! I learned something new for me today about class methods (Ruby style).
Well... the answer is NO if you think from the perspective of how an overriden method should behave in Java. But, you don't get any compiler error if you try to override a static method. That means, if you try to override, Java doesn't stop you doing that; but you certainly don't get the same effect as you get for non-static methods. Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it (which is the case with overriden static methods). Okay... any guesses for the reason why do they behave strangely? Because they are class methods and hence access to them is always resolved during compile time only using the compile time type information. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it :-)
Example: let's try to see what happens if we try overriding a static method:-
class SuperClass {
// ......
public static void staticMethod() {
System.out.println("SuperClass: inside staticMethod");
}
// ......
}
public class SubClass extends SuperClass {
// ......
// overriding the static method
public static void staticMethod() {
System.out.println("SubClass: inside staticMethod");
}
// ......
public static void main(String[] args) {
// ......
SuperClass superClassWithSuperCons = new SuperClass();
SuperClass superClassWithSubCons = new SubClass();
SubClass subClassWithSubCons = new SubClass();
superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
// ...
}
}
Output:-
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Notice the second line of the output. Had the staticMethod been overriden this line should have been identical to the third line as we're invoking the 'staticMethod()' on an object of Runtime Type as 'SubClass' and not as 'SuperClass'. This confirms that the static methods are always resolved using their compile time type information only.
I like and double Jay's comment (https://stackoverflow.com/a/2223803/1517187).
I agree that this is the bad design of Java.
Many other languages support overriding static methods, as we see in previous comments.
I feel Jay has also come to Java from Delphi like me.
Delphi (Object Pascal) was one of the languages implementing OOP before Java and one of the first languages used for commercial application development.
It is obvious that many people had experience with that language since it was in the past the only language to write commercial GUI products. And - yes, we could in Delphi override static methods. Actually, static methods in Delphi are called "class methods", while Delphi had the different concept of "Delphi static methods" which were methods with early binding. To override methods you had to use late binding, declare "virtual" directive. So it was very convenient and intuitive and I would expect this in Java.
In general it doesn't make sense to allow 'overriding' of static methods as there would be no good way to determine which one to call at runtime. Taking the Employee example, if we call RegularEmployee.getBonusMultiplier() - which method is supposed to be executed?
In the case of Java, one could imagine a language definition where it is possible to 'override' static methods as long as they are called through an object instance. However, all this would do is to re-implement regular class methods, adding redundancy to the language without really adding any benefit.
overriding is reserved for instance members to support polymorphic behaviour. static class members do not belong to a particular instance. instead, static members belong to the class and as a result overriding is not supported because subclasses only inherit protected and public instance members and not static members. You may want to define an inerface and research factory and/or strategy design patterns to evaluate an alternate approach.
By overriding we can create a polymorphic nature depending on the object type. Static method has no relation with object. So java can not support static method overriding.
By overriding, you achieve dynamic polymorphism.
When you say overriding static methods, the words you are trying to use are contradictory.
Static says - compile time, overriding is used for dynamic polymorphism.
Both are opposite in nature, and hence can't be used together.
Dynamic polymorphic behavior comes when a programmer uses an object and accessing an instance method. JRE will map different instance methods of different classes based on what kind of object you are using.
When you say overriding static methods, static methods we will access by using the class name, which will be linked at compile time, so there is no concept of linking methods at runtime with static methods. So the term "overriding" static methods itself doesn't make any meaning.
Note: even if you access a class method with an object, still java compiler is intelligent enough to find it out, and will do static linking.
Overriding in Java simply means that the particular method would be called based on the runtime type
of the object and not on the compile-time type of it (which is the case with overridden static methods). As static methods are class methods they are not instance methods so they have nothing to do with the fact which reference is pointing to which Object or instance, because due to the nature of static method it belongs to a specific class. You can redeclare it in the subclass but that subclass won't know anything about the parent class' static methods because, as I said, it is specific to only that class in which it has been declared. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it
more details and example
http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
What good will it do to override static methods. You cannot call static methods through an instance.
MyClass.static1()
MySubClass.static1() // If you overrode, you have to call it through MySubClass anyway.
EDIT : It appears that through an unfortunate oversight in language design, you can call static methods through an instance. Generally nobody does that. My bad.
Answer of this question is simple, the method or variable marked as static belongs to the class only, So that static method cannot be inherited in the sub class because they belong to the super class only.
Easy solution: Use singleton instance. It will allow overrides and inheritance.
In my system, I have SingletonsRegistry class, which returns instance for passed Class. If instance is not found, it is created.
Haxe language class:
package rflib.common.utils;
import haxe.ds.ObjectMap;
class SingletonsRegistry
{
public static var instances:Map<Class<Dynamic>, Dynamic>;
static function __init__()
{
StaticsInitializer.addCallback(SingletonsRegistry, function()
{
instances = null;
});
}
public static function getInstance(cls:Class<Dynamic>, ?args:Array<Dynamic>)
{
if (instances == null) {
instances = untyped new ObjectMap<Dynamic, Dynamic>();
}
if (!instances.exists(cls))
{
if (args == null) args = [];
instances.set(cls, Type.createInstance(cls, args));
}
return instances.get(cls);
}
public static function validate(inst:Dynamic, cls:Class<Dynamic>)
{
if (instances == null) return;
var inst2 = instances[cls];
if (inst2 != null && inst != inst2) throw "Can\'t create multiple instances of " + Type.getClassName(cls) + " - it's singleton!";
}
}
A Static method, variable, block or nested class belongs to the entire class rather than an object.
A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (i.e, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming i.e, high cohesion. (remember a constructor is a special kind of method in Java.)
High Cohesion - One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.
Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.
The below piece code tries to override the static method, but will not encounter any compilation error.
public class Vehicle {
static int VIN;
public static int getVehileNumber() {
return VIN;
}}
class Car extends Vehicle {
static int carNumber;
public static int getVehileNumber() {
return carNumber;
}}
This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).
Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.
Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.
public static final int getVehileNumber() {
return VIN; }
Overall, this is upto software designers for where to use the static methods.
I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.
Here is a simple explanation. A static method is associated with a class while an instance method is associated with a particular object. Overrides allow calling the different implementation of the overridden methods associated with the particular object. So it is counter-intuitive to override static method which is not even associated with objects but the class itself in the first place. So static methods cannot be overridden based on what object is calling it, it will always be associated with the class where it was created.
Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass.
We can access static methods of super class with subclass reference if this static method has not been hidden by new static method defined in sub class.
For Example, see below code:-
public class StaticMethodsHiding {
public static void main(String[] args) {
SubClass.hello();
}
}
class SuperClass {
static void hello(){
System.out.println("SuperClass saying Hello");
}
}
class SubClass extends SuperClass {
// static void hello() {
// System.out.println("SubClass Hello");
// }
}
Output:-
SuperClass saying Hello
See Java oracle docs and search for What You Can Do in a Subclass for details about hiding of static methods in sub class.
Thanks
The following code shows that it is possible:
class OverridenStaticMeth {
static void printValue() {
System.out.println("Overriden Meth");
}
}
public class OverrideStaticMeth extends OverridenStaticMeth {
static void printValue() {
System.out.println("Overriding Meth");
}
public static void main(String[] args) {
OverridenStaticMeth osm = new OverrideStaticMeth();
osm.printValue();
System.out.println("now, from main");
printValue();
}
}
Why is it not possible to override static methods?
If possible, please use an example.
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.
Personally I think this is a flaw in the design of Java. Yes, yes, I understand that non-static methods are attached to an instance while static methods are attached to a class, etc etc. Still, consider the following code:
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(getBonusMultiplier());
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
This code will not work as you might expect. Namely, SpecialEmployee's get a 2% bonus just like regular employees. But if you remove the "static"s, then SpecialEmployee's get a 3% bonus.
(Admittedly, this example is poor coding style in that in real life you would likely want the bonus multiplier to be in a database somewhere rather than hard-coded. But that's just because I didn't want to bog down the example with a lot of code irrelevant to the point.)
It seems quite plausible to me that you might want to make getBonusMultiplier static. Perhaps you want to be able to display the bonus multiplier for all the categories of employees, without needing to have an instance of an employee in each category. What would be the point of searching for such example instances? What if we are creating a new category of employee and don't have any employees assigned to it yet? This is quite logically a static function.
But it doesn't work.
And yes, yes, I can think of any number of ways to rewrite the above code to make it work. My point is not that it creates an unsolvable problem, but that it creates a trap for the unwary programmer, because the language does not behave as I think a reasonable person would expect.
Perhaps if I tried to write a compiler for an OOP language, I would quickly see why implementing it so that static functions can be overriden would be difficult or impossible.
Or perhaps there is some good reason why Java behaves this way. Can anyone point out an advantage to this behavior, some category of problem that is made easier by this? I mean, don't just point me to the Java language spec and say "see, this is documented how it behaves". I know that. But is there a good reason why it SHOULD behave this way? (Besides the obvious "making it work right was too hard"...)
Update
#VicKirk: If you mean that this is "bad design" because it doesn't fit how Java handles statics, my reply is, "Well, duh, of course." As I said in my original post, it doesn't work. But if you mean that it is bad design in the sense that there would be something fundamentally wrong with a language where this worked, i.e. where statics could be overridden just like virtual functions, that this would somehow introduce an ambiguity or it would be impossible to implement efficiently or some such, I reply, "Why? What's wrong with the concept?"
I think the example I give is a very natural thing to want to do. I have a class that has a function that does not depend on any instance data, and which I might very reasonably want to call independent of an instance, as well as wanting to call from within an instance method. Why should this not work? I've run into this situation a fair number of times over the years. In practice I get around it by making the function virtual, and then creating a static method whose only purpose in life is to be a static method that passes the call on to the virtual method with a dummy instance. That seems like a very roundabout way to get there.
The short answer is: it is entirely possible, but Java doesn't do it.
Here is some code which illustrates the current state of affairs in Java:
File Base.java:
package sp.trial;
public class Base {
static void printValue() {
System.out.println(" Called static Base method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Base method.");
}
void nonLocalIndirectStatMethod() {
System.out.println(" Non-static calls overridden(?) static:");
System.out.print(" ");
this.printValue();
}
}
File Child.java:
package sp.trial;
public class Child extends Base {
static void printValue() {
System.out.println(" Called static Child method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Child method.");
}
void localIndirectStatMethod() {
System.out.println(" Non-static calls own static:");
System.out.print(" ");
printValue();
}
public static void main(String[] args) {
System.out.println("Object: static type Base; runtime type Child:");
Base base = new Child();
base.printValue();
base.nonStatPrintValue();
System.out.println("Object: static type Child; runtime type Child:");
Child child = new Child();
child.printValue();
child.nonStatPrintValue();
System.out.println("Class: Child static call:");
Child.printValue();
System.out.println("Class: Base static call:");
Base.printValue();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Child:");
child.localIndirectStatMethod();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Base:");
child.nonLocalIndirectStatMethod();
}
}
If you run this (I did it on a Mac, from Eclipse, using Java 1.6) you get:
Object: static type Base; runtime type Child.
Called static Base method.
Called non-static Child method.
Object: static type Child; runtime type Child.
Called static Child method.
Called non-static Child method.
Class: Child static call.
Called static Child method.
Class: Base static call.
Called static Base method.
Object: static/runtime type Child -- call static from non-static method of Child.
Non-static calls own static.
Called static Child method.
Object: static/runtime type Child -- call static from non-static method of Base.
Non-static calls overridden(?) static.
Called static Base method.
Here, the only cases which might be a surprise (and which the question is about) appear to be the first case:
"The run-time type is not used to determine which static methods are called, even when called with an object instance (obj.staticMethod())."
and the last case:
"When calling a static method from within an object method of a class, the static method chosen is the one accessible from the class itself and not from the class defining the run-time type of the object."
Calling with an object instance
The static call is resolved at compile-time, whereas a non-static method call is resolved at run-time. Notice that although static methods are inherited (from parent) they are not overridden (by child). This could be a surprise if you expected otherwise.
Calling from within an object method
Object method calls are resolved using the run-time type, but static (class) method calls are resolved using the compile-time (declared) type.
Changing the rules
To change these rules, so that the last call in the example called Child.printValue(), static calls would have to be provided with a type at run-time, rather than the compiler resolving the call at compile-time with the declared class of the object (or context). Static calls could then use the (dynamic) type hierarchy to resolve the call, just as object method calls do today.
This would easily be doable (if we changed Java :-O), and is not at all unreasonable, however, it has some interesting considerations.
The main consideration is that we need to decide which static method calls should do this.
At the moment, Java has this "quirk" in the language whereby obj.staticMethod() calls are replaced by ObjectClass.staticMethod() calls (normally with a warning). [Note: ObjectClass is the compile-time type of obj.] These would be good candidates for overriding in this way, taking the run-time type of obj.
If we did it would make method bodies harder to read: static calls in a parent class could potentially be dynamically "re-routed". To avoid this we would have to call the static method with a class name -- and this makes the calls more obviously resolved with the compile-time type hierarchy (as now).
The other ways of invoking a static method are more tricky: this.staticMethod() should mean the same as obj.staticMethod(), taking the run-time type of this. However, this might cause some headaches with existing programs, which call (apparently local) static methods without decoration (which is arguably equivalent to this.method()).
So what about unadorned calls staticMethod()? I suggest they do the same as today, and use the local class context to decide what to do. Otherwise great confusion would ensue. Of course it means that method() would mean this.method() if method was a non-static method, and ThisClass.method() if method were a static method. This is another source of confusion.
Other considerations
If we changed this behaviour (and made static calls potentially dynamically non-local), we would probably want to revisit the meaning of final, private and protected as qualifiers on static methods of a class. We would then all have to get used to the fact that private static and public final methods are not overridden, and can therefore be safely resolved at compile-time, and are "safe" to read as local references.
Actually we were wrong.
Despite Java doesn't allow you to override static methods by default, if you look thoroughly through documentation of Class and Method classes in Java, you can still find a way to emulate static methods overriding by following workaround:
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
class RegularEmployee {
private BigDecimal salary = BigDecimal.ONE;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(this.getBonusMultiplier());
}
public BigDecimal calculateOverridenBonus() {
try {
// System.out.println(this.getClass().getDeclaredMethod(
// "getBonusMultiplier").toString());
try {
return salary.multiply((BigDecimal) this.getClass()
.getDeclaredMethod("getBonusMultiplier").invoke(this));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
// ... presumably lots of other code ...
}
final class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
public class StaticTestCoolMain {
static public void main(String[] args) {
RegularEmployee Alan = new RegularEmployee();
System.out.println(Alan.calculateBonus());
System.out.println(Alan.calculateOverridenBonus());
SpecialEmployee Bob = new SpecialEmployee();
System.out.println(Bob.calculateBonus());
System.out.println(Bob.calculateOverridenBonus());
}
}
Resulting output:
0.02
0.02
0.02
0.03
what we were trying to achieve :)
Even if we declare third variable Carl as RegularEmployee and assign to it instance of SpecialEmployee, we will still have call of RegularEmployee method in first case and call of SpecialEmployee method in second case
RegularEmployee Carl = new SpecialEmployee();
System.out.println(Carl.calculateBonus());
System.out.println(Carl.calculateOverridenBonus());
just look at output console:
0.02
0.03
;)
Static methods are treated as global by the JVM, there are not bound to an object instance at all.
It could conceptually be possible if you could call static methods from class objects (like in languages like Smalltalk) but it's not the case in Java.
EDIT
You can overload static method, that's ok. But you can not override a static method, because class are no first-class object. You can use reflection to get the class of an object at run-time, but the object that you get does not parallel the class hierarchy.
class MyClass { ... }
class MySubClass extends MyClass { ... }
MyClass obj1 = new MyClass();
MySubClass obj2 = new MySubClass();
ob2 instanceof MyClass --> true
Class clazz1 = obj1.getClass();
Class clazz2 = obj2.getClass();
clazz2 instanceof clazz1 --> false
You can reflect over the classes, but it stops there. You don't invoke a static method by using clazz1.staticMethod(), but using MyClass.staticMethod(). A static method is not bound to an object and there is hence no notion of this nor super in a static method. A static method is a global function; as a consequence there is also no notion of polymorphism and, therefore, method overriding makes no sense.
But this could be possible if MyClass was an object at run-time on which you invoke a method, as in Smalltalk (or maybe JRuby as one comment suggest, but I know nothing of JRuby).
Oh yeah... one more thing. You can invoke a static method through an object obj1.staticMethod() but that really syntactic sugar for MyClass.staticMethod() and should be avoided. It usually raises a warning in modern IDE. I don't know why they ever allowed this shortcut.
Method overriding is made possible by dynamic dispatching, meaning that the declared type of an object doesn't determine its behavior, but rather its runtime type:
Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"
Even though both lassie and kermit are declared as objects of type Animal, their behavior (method .speak()) varies because dynamic dispatching will only bind the method call .speak() to an implementation at run time - not at compile time.
Now, here's where the static keyword starts to make sense: the word "static" is an antonym for "dynamic". So the reason why you can't override static methods is because there is no dynamic dispatching on static members - because static literally means "not dynamic". If they dispatched dynamically (and thus could be overriden) the static keyword just wouldn't make sense anymore.
Yes. Practically Java allows overriding static method, and No theoretically if you Override a static method in Java then it will compile and run smoothly but it will lose Polymorphism which is the basic property of Java. You will Read Everywhere that it is not possible to try yourself compiling and running. you will get your answer. e.g. If you Have Class Animal and a static method eat() and you Override that static method in its Subclass lets called it Dog. Then when wherever you Assign a Dog object to an Animal Reference and call eat() according to Java Dog's eat() should have been called but in static Overriding Animals' eat() will Be Called.
class Animal {
public static void eat() {
System.out.println("Animal Eating");
}
}
class Dog extends Animal{
public static void eat() {
System.out.println("Dog Eating");
}
}
class Test {
public static void main(String args[]) {
Animal obj= new Dog();//Dog object in animal
obj.eat(); //should call dog's eat but it didn't
}
}
Output Animal Eating
According to Polymorphism Principle of Java, the Output Should be Dog Eating.
But the result was different because to support Polymorphism Java uses Late Binding that means methods are called only at the run-time but not in the case of static methods. In static methods compiler calls methods at the compile time rather than the run-time, so we get methods according to the reference and not according to the object a reference a containing that's why You can say Practically it supports static overring but theoretically, it doesn't.
In Java (and many OOP languages, but I cannot speak for all; and some do not have static at all) all methods have a fixed signature - the parameters and types. In a virtual method, the first parameter is implied: a reference to the object itself and when called from within the object, the compiler automatically adds this.
There is no difference for static methods - they still have a fixed signature. However, by declaring the method static you have explicitly stated that the compiler must not include the implied object parameter at the beginning of that signature. Therefore, any other code that calls this must must not attempt to put a reference to an object on the stack. If it did do that, then the method execution would not work since the parameters would be in the wrong place - shifted by one - on the stack.
Because of this difference between the two; virtual methods always have a reference to the context object (i.e. this) so then it is possible to reference anything within the heap that belong to that instance of the object. But with static methods, since there is no reference passed, that method cannot access any object variables and methods since the context is not known.
If you wish that Java would change the definition so that a object context is passed in for every method, static or virtual, then you would in essence have only virtual methods.
As someone asked in a comment to the op - what is your reason and purpose for wanting this feature?
I do not know Ruby much, as this was mentioned by the OP, I did some research. I see that in Ruby classes are really a special kind of object and one can create (even dynamically) new methods. Classes are full class objects in Ruby, they are not in Java. This is just something you will have to accept when working with Java (or C#). These are not dynamic languages, though C# is adding some forms of dynamic. In reality, Ruby does not have "static" methods as far as I could find - in that case these are methods on the singleton class object. You can then override this singleton with a new class and the methods in the previous class object will call those defined in the new class (correct?). So if you called a method in the context of the original class it still would only execute the original statics, but calling a method in the derived class, would call methods either from the parent or sub-class. Interesting and I can see some value in that. It takes a different thought pattern.
Since you are working in Java, you will need to adjust to that way of doing things. Why they did this? Well, probably to improve performance at the time based on the technology and understanding that was available. Computer languages are constantly evolving. Go back far enough and there is no such thing as OOP. In the future, there will be other new ideas.
EDIT: One other comment. Now that I see the differences and as I Java/C# developer myself, I can understand why the answers you get from Java developers may be confusing if you are coming from a language like Ruby. Java static methods are not the same as Ruby class methods. Java developers will have a hard time understanding this, as will conversely those who work mostly with a language like Ruby/Smalltalk. I can see how this would also be greatly confusing by the fact that Java also uses "class method" as another way to talk about static methods but this same term is used differently by Ruby. Java does not have Ruby style class methods (sorry); Ruby does not have Java style static methods which are really just old procedural style functions, as found in C.
By the way - thanks for the question! I learned something new for me today about class methods (Ruby style).
Well... the answer is NO if you think from the perspective of how an overriden method should behave in Java. But, you don't get any compiler error if you try to override a static method. That means, if you try to override, Java doesn't stop you doing that; but you certainly don't get the same effect as you get for non-static methods. Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it (which is the case with overriden static methods). Okay... any guesses for the reason why do they behave strangely? Because they are class methods and hence access to them is always resolved during compile time only using the compile time type information. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it :-)
Example: let's try to see what happens if we try overriding a static method:-
class SuperClass {
// ......
public static void staticMethod() {
System.out.println("SuperClass: inside staticMethod");
}
// ......
}
public class SubClass extends SuperClass {
// ......
// overriding the static method
public static void staticMethod() {
System.out.println("SubClass: inside staticMethod");
}
// ......
public static void main(String[] args) {
// ......
SuperClass superClassWithSuperCons = new SuperClass();
SuperClass superClassWithSubCons = new SubClass();
SubClass subClassWithSubCons = new SubClass();
superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
// ...
}
}
Output:-
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Notice the second line of the output. Had the staticMethod been overriden this line should have been identical to the third line as we're invoking the 'staticMethod()' on an object of Runtime Type as 'SubClass' and not as 'SuperClass'. This confirms that the static methods are always resolved using their compile time type information only.
I like and double Jay's comment (https://stackoverflow.com/a/2223803/1517187).
I agree that this is the bad design of Java.
Many other languages support overriding static methods, as we see in previous comments.
I feel Jay has also come to Java from Delphi like me.
Delphi (Object Pascal) was one of the languages implementing OOP before Java and one of the first languages used for commercial application development.
It is obvious that many people had experience with that language since it was in the past the only language to write commercial GUI products. And - yes, we could in Delphi override static methods. Actually, static methods in Delphi are called "class methods", while Delphi had the different concept of "Delphi static methods" which were methods with early binding. To override methods you had to use late binding, declare "virtual" directive. So it was very convenient and intuitive and I would expect this in Java.
In general it doesn't make sense to allow 'overriding' of static methods as there would be no good way to determine which one to call at runtime. Taking the Employee example, if we call RegularEmployee.getBonusMultiplier() - which method is supposed to be executed?
In the case of Java, one could imagine a language definition where it is possible to 'override' static methods as long as they are called through an object instance. However, all this would do is to re-implement regular class methods, adding redundancy to the language without really adding any benefit.
overriding is reserved for instance members to support polymorphic behaviour. static class members do not belong to a particular instance. instead, static members belong to the class and as a result overriding is not supported because subclasses only inherit protected and public instance members and not static members. You may want to define an inerface and research factory and/or strategy design patterns to evaluate an alternate approach.
By overriding we can create a polymorphic nature depending on the object type. Static method has no relation with object. So java can not support static method overriding.
By overriding, you achieve dynamic polymorphism.
When you say overriding static methods, the words you are trying to use are contradictory.
Static says - compile time, overriding is used for dynamic polymorphism.
Both are opposite in nature, and hence can't be used together.
Dynamic polymorphic behavior comes when a programmer uses an object and accessing an instance method. JRE will map different instance methods of different classes based on what kind of object you are using.
When you say overriding static methods, static methods we will access by using the class name, which will be linked at compile time, so there is no concept of linking methods at runtime with static methods. So the term "overriding" static methods itself doesn't make any meaning.
Note: even if you access a class method with an object, still java compiler is intelligent enough to find it out, and will do static linking.
Overriding in Java simply means that the particular method would be called based on the runtime type
of the object and not on the compile-time type of it (which is the case with overridden static methods). As static methods are class methods they are not instance methods so they have nothing to do with the fact which reference is pointing to which Object or instance, because due to the nature of static method it belongs to a specific class. You can redeclare it in the subclass but that subclass won't know anything about the parent class' static methods because, as I said, it is specific to only that class in which it has been declared. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it
more details and example
http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
What good will it do to override static methods. You cannot call static methods through an instance.
MyClass.static1()
MySubClass.static1() // If you overrode, you have to call it through MySubClass anyway.
EDIT : It appears that through an unfortunate oversight in language design, you can call static methods through an instance. Generally nobody does that. My bad.
Answer of this question is simple, the method or variable marked as static belongs to the class only, So that static method cannot be inherited in the sub class because they belong to the super class only.
Easy solution: Use singleton instance. It will allow overrides and inheritance.
In my system, I have SingletonsRegistry class, which returns instance for passed Class. If instance is not found, it is created.
Haxe language class:
package rflib.common.utils;
import haxe.ds.ObjectMap;
class SingletonsRegistry
{
public static var instances:Map<Class<Dynamic>, Dynamic>;
static function __init__()
{
StaticsInitializer.addCallback(SingletonsRegistry, function()
{
instances = null;
});
}
public static function getInstance(cls:Class<Dynamic>, ?args:Array<Dynamic>)
{
if (instances == null) {
instances = untyped new ObjectMap<Dynamic, Dynamic>();
}
if (!instances.exists(cls))
{
if (args == null) args = [];
instances.set(cls, Type.createInstance(cls, args));
}
return instances.get(cls);
}
public static function validate(inst:Dynamic, cls:Class<Dynamic>)
{
if (instances == null) return;
var inst2 = instances[cls];
if (inst2 != null && inst != inst2) throw "Can\'t create multiple instances of " + Type.getClassName(cls) + " - it's singleton!";
}
}
A Static method, variable, block or nested class belongs to the entire class rather than an object.
A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (i.e, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming i.e, high cohesion. (remember a constructor is a special kind of method in Java.)
High Cohesion - One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.
Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.
The below piece code tries to override the static method, but will not encounter any compilation error.
public class Vehicle {
static int VIN;
public static int getVehileNumber() {
return VIN;
}}
class Car extends Vehicle {
static int carNumber;
public static int getVehileNumber() {
return carNumber;
}}
This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).
Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.
Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.
public static final int getVehileNumber() {
return VIN; }
Overall, this is upto software designers for where to use the static methods.
I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.
Here is a simple explanation. A static method is associated with a class while an instance method is associated with a particular object. Overrides allow calling the different implementation of the overridden methods associated with the particular object. So it is counter-intuitive to override static method which is not even associated with objects but the class itself in the first place. So static methods cannot be overridden based on what object is calling it, it will always be associated with the class where it was created.
Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass.
We can access static methods of super class with subclass reference if this static method has not been hidden by new static method defined in sub class.
For Example, see below code:-
public class StaticMethodsHiding {
public static void main(String[] args) {
SubClass.hello();
}
}
class SuperClass {
static void hello(){
System.out.println("SuperClass saying Hello");
}
}
class SubClass extends SuperClass {
// static void hello() {
// System.out.println("SubClass Hello");
// }
}
Output:-
SuperClass saying Hello
See Java oracle docs and search for What You Can Do in a Subclass for details about hiding of static methods in sub class.
Thanks
The following code shows that it is possible:
class OverridenStaticMeth {
static void printValue() {
System.out.println("Overriden Meth");
}
}
public class OverrideStaticMeth extends OverridenStaticMeth {
static void printValue() {
System.out.println("Overriding Meth");
}
public static void main(String[] args) {
OverridenStaticMeth osm = new OverrideStaticMeth();
osm.printValue();
System.out.println("now, from main");
printValue();
}
}
I do know the syntactical difference between overriding and overloading. And I also know that overriding is run-time polymorphism and overloading is compile-time polymorphism. But my question is: "Is overloading is really compile-time polymorphism? Is the method call really solving at compile time?". To clarify my point, let's consider an example class.
public class Greeter {
public void greetMe() {
System.out.println("Hello");
}
public void greetMe(String name) {
System.out.println("Hello " + name);
}
public void wishLuck() {
System.out.println("Good Luck");
}
}
Since all of the methods greetMe(), greetMe(String name), wishLuck() are public, they all can be overriden(including overloaded one), right? For example,
public class FancyGreeter extends Greeter {
public void greetMe() {
System.out.println("***********");
System.out.println("* Hello *");
System.out.println("***********");
}
}
Now, consider the following snippet:
Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();
The getRandomGreeter() method returns a random Greeter object. It may either return an object of Greeter, or any of its subclasses, like FancyGreeter or GraphicalGreeter or any other one. The getRandomGreeter() will create the objects either using new or dynamically load the class file and create object using reflection(I think it is possible with reflection) or any other way that is possible. All of these methods of Greeter may or may not be overriden in subclasses. So the compiler has no way to know whether a particular method(overloaded or not) is overriden. Right? Also, wikipedia says on Virtual functions:
In Java, all non-static methods are by default "virtual functions".
Only methods marked with the keyword final, which cannot be overridden,
along with private methods, which are not inherited, are non-virtual.
Since, virtual functions are resolved at run-time using dynamic method dispatch, and since all non private, non final methods are virtual(whether overloaded or not), they must be resolved at run-time. Right?
Then, How can overloading still be resolved at compile-time? Or, is there anything that I misunderstood, or am I missing?
Every 'Greeter' class has 3 virtual methods: void greetMe(), void greetMe(String), and void wishLuck().
When you call greeter.greetMe() the compiler can work out which one of the three virtual methods should be called from the method signature - ie. the void greetMe() one since it accepts no arguments. Which specific implementation of the void greetMe() method is called depends on the type of the greeter instance, and is resolved at run-time.
In your example it's trivial for the compiler to work out which method to call, since the method signatures are all completely different. A slightly better example for showing the 'compile time polymorphism' concept might be as follows:
class Greeter {
public void greetMe(Object obj) {
System.out.println("Hello Object!");
}
public void greetMe(String str) {
System.out.println("Hello String!");
}
}
Using this greeter class will give the following results:
Object obj = new Object();
String str = "blah";
Object strAsObj = str;
greeter.greetMe(obj); // prints "Hello Object!"
greeter.greetMe(str); // prints "Hello String!"
greeter.greetMe(strAsObj); // prints "Hello Object!"
The compiler will pick out the method with the most specific match using the compile-time type, which is why the 2nd example works and calls the void greetMe(String) method.
The last call is the most interesting one: Even though the run-time type of strAsObj is String, it has been cast as an Object so that's how the compiler sees it. So, the closest match the compiler can find for that call is the void greetMe(Object) method.
Overloaded methods can still be overridden, if that is what you ask.
Overloaded methods are like different families, even though they share the same name. The compiler statically chooses one family given the signature, and then at run time it is dispatched to the most specific method in the class hierarchy.
That is, method dispatching is performed in two steps:
The first one is done at compile time with the static information available, the compiler will emit a call for the signature that matches best your current method parameters among the list of overloaded methods in the declared type of the object the method is invoked upon.
The second step is performed at run time, given the method signature that should be called (previous step, remember?), the JVM will dispatch it to the most concrete overridden version in the actual type of receiver object.
If the method arguments types are not covariant at all, overloading is equivalent to having methods names mangled at compile time; because they are effectively different methods, the JVM won't never ever dispatch them interchangeably depending on the type of the receiver.
What is polymorphism?
Acc. to me: if an entity can be represented in more than one forms, that entity is said to exhibit polymorphism.
Now, lets apply this definition to Java constructs:
1) Operator overloading is compile time polymorphism.
For example, + operator can be used to add two numbers OR to concatenate two strings. it's an example of polymorphism strictly saying compile-time polymorphism.
2) Method overloading is compile time polymorphism.
For example, a method with same name can have more than one implemntations. it's also a compile-time polymorphism.
It's compile-time because before execution of program compiler decides the flow of program i.e which form will be used during run-time.
3) Method overriding is run-time polymorphism.
For example, a method with same signature can have more than one implemenations. it's a run time polymorphism.
4) Base class use in place of derived class is run time polymorphism.
For example, an interface reference can point to any of it's implementor.
It's run-time because the flow of program can't be known before execution i.e. only during run-time it can be decided that which form will be used.
I hope it clears a bit.
Overloading in this respect means that the type of the function is statically determined at compile time as opposed to dynamic dispatch.
What really happens behind the scenes is that for a method named "foo" with types "A" and "B" two methods are created ("foo_A" and "foo_B"). Which of them is to be called is determined at compile-time (foo((A) object) or foo((B) object) result in foo_A being called or foo_B). So in a way this is compile-time polymorphism, although the real method (i.e. which implementation in the class hierarchy to take) is determined at runtime.
I have strong objection to call method overloading as compile time polymorphism.
I agree that method overloading is static binding(compile time) but i didn't see polymorphism in that.
I tried to put my opinion in my question to get clarification. you can refer this link.
Overriding a method can be prevented by using the keyword final, likewise how to prevent overloading?
You can't. Because it's almost pointless.
If you want to overload the method handle(..) but you are disallowed to, you'd create doHandle(..) instead.
Which overloaded method is used is determined at compile time (in contrast to overridden methods, which are determined at runtime). So the point of overloading is sharing a common name for common operations. Disallowing that is a matter of code-style, rather than anything else.
You can't do that in Java.
An overloaded method is basically just another method.
An attempt could look (something) like this
void yourMethod(String arg) { /* ... */ }
void yourMethod(String arg, Object... prevent) {
throw new IllegalArgumentException();
}
but it won't work since Java resolves overloading by looking at the "best match" or "most specific signature".
The method could still be overloaded with a
void yourMethod(String arg, String arg2) { /* ... */ }
which would be called when doing yourMethod("hello", "world").
Btw, why would you want to prevent overloading? Perhaps there is another way of doing what you want?
Err... what's the point in not allowing to Overload the method?
Protection from Overriding is allowed because it can be done by another programmer who is supposedly working on another part of code and his class is inherited from your class.
Overloading is done in the same class and is logically supposed to be done by a programmer who knows this code and is working on the same part of the code. So, if he knows this code (theoretically) and there is some inherent danger in overloading, then he should know this already because he knows the code.
That said, overloading cannot be stopped as others have already described.
Mark the class final and it can't be extended. That may defeat some other purpose though.
If you overload a method, you've created a method with the same name but different parameter types. In Java, a method is defined (partly) in terms of its parameters, and thus if two methods have the same name but different parameters, then they are apples and oranges, i.e., not the same. In short, you can't prevent someone from creating new methods in a class, which is essentially what you're asking for.
simple! don't call that overloaded method.
public class Test
{
public void m(int a)
{
*your definition*
}
public void m(float a)
{
*your definition*
}
}
public static void main(Strings [] args)
{
Test t=new Test();
t.m(5);
}
Overriding and Overloading are different techniques. Overloading is a way of declaring multiple methods with the same names but different parameter types or different no of parameters.
You can prevent a method from being overwritten by making it final, but you cannot prevent a method from being overloaded. Well technically you could make the class itself final, so that no methods at all can be added by creating a subclass but I don't think that's a good design.
I know that calling a virtual method from a base class constructor can be dangerous since the child class might not be in a valid state. (at least in C#)
My question is what if the virtual method is the one who initializes the state of the object ? Is it good practice or should it be a two step process, first to create the object and then to load the state ?
First option: (using the constructor to initialize the state)
public class BaseObject {
public BaseObject(XElement definition) {
this.LoadState(definition);
}
protected abstract LoadState(XElement definition);
}
Second option: (using a two step process)
public class BaseObject {
public void LoadState(XElement definition) {
this.LoadStateCore(definition);
}
protected abstract LoadStateCore(XElement definition);
}
In the first method the consumer of the code can create and initialize the object with one statement:
// The base class will call the virtual method to load the state.
ChildObject o = new ChildObject(definition)
In the second method the consumer will have to create the object and then load the state:
ChildObject o = new ChildObject();
o.LoadState(definition);
(This answer applies to C# and Java. I believe C++ works differently on this matter.)
Calling a virtual method in a constructor is indeed dangerous, but sometimes it can end up with the cleanest code.
I would try to avoid it where possible, but without bending the design hugely. (For instance, the "initialize later" option prohibits immutability.) If you do use a virtual method in the constructor, document it very strongly. So long as everyone involved is aware of what it's doing, it shouldn't cause too many problems. I would try to limit the visibility though, as you've done in your first example.
EDIT: One thing which is important here is that there's a difference between C# and Java in order of initialization. If you have a class such as:
public class Child : Parent
{
private int foo = 10;
protected override void ShowFoo()
{
Console.WriteLine(foo);
}
}
where the Parent constructor calls ShowFoo, in C# it will display 10. The equivalent program in Java would display 0.
In C++, calling a virtual method in a base class constructor will simply call the method as if the derived class doesn't exist yet (because it doesn't). So that means that the call is resolved at compile time to whatever method it should call in the base class (or classes it derived from).
Tested with GCC, it allows you to call a pure virtual function from a constructor, but it gives a warning, and results in a link time error. It appears that this behavior is undefined by the standard:
"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (class.virtual) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."
With C++ the virtual methods are routed through the vtable for the class that is being constructed. So in your example it would generate a pure virtual method exception since whilst BaseObject is being constructed there simply is no LoadStateCore method to invoke.
If the function is not abstract, but simply does nothing then you will often get the programmer scratching their head for a while trying to remember why it is that the function doesn't actually get called.
For this reason you simply can't do it this way in C++ ...
For C++ the base constructor is called before the derived constructor, which means that the virtual table (which holds the addresses of the derived class's overridden virtual functions) does not yet exist. For this reason, it is considered a VERY dangerous thing to do (especially if the functions are pure virtual in the base class...this will cause a pure-virtual exception).
There are two ways around this:
Do a two-step process of construction + initialization
Move the virtual functions to an internal class that you can more closely control (can make use of the above approach, see example for details)
An example of (1) is:
class base
{
public:
base()
{
// only initialize base's members
}
virtual ~base()
{
// only release base's members
}
virtual bool initialize(/* whatever goes here */) = 0;
};
class derived : public base
{
public:
derived ()
{
// only initialize derived 's members
}
virtual ~derived ()
{
// only release derived 's members
}
virtual bool initialize(/* whatever goes here */)
{
// do your further initialization here
// return success/failure
}
};
An example of (2) is:
class accessible
{
private:
class accessible_impl
{
protected:
accessible_impl()
{
// only initialize accessible_impl's members
}
public:
static accessible_impl* create_impl(/* params for this factory func */);
virtual ~accessible_impl()
{
// only release accessible_impl's members
}
virtual bool initialize(/* whatever goes here */) = 0;
};
accessible_impl* m_impl;
public:
accessible()
{
m_impl = accessible_impl::create_impl(/* params to determine the exact type needed */);
if (m_impl)
{
m_impl->initialize(/* ... */); // add any initialization checking you need
}
}
virtual ~accessible()
{
if (m_impl)
{
delete m_impl;
}
}
/* Other functionality of accessible, which may or may not use the impl class */
};
Approach (2) uses the Factory pattern to provide the appropriate implementation for the accessible class (which will provide the same interface as your base class). One of the main benefits here is that you get initialization during construction of accessible that is able to make use of virtual members of accessible_impl safely.
For C++, section 12.7, paragraph 3 of the Standard covers this case.
To summarize, this is legal. It will resolve to the correct function to the type of the constructor being run. Therefore, adapting your example to C++ syntax, you'd be calling BaseObject::LoadState(). You can't get to ChildObject::LoadState(), and trying to do so by specifying the class as well as the function results in undefined behavior.
Constructors of abstract classes are covered in section 10.4, paragraph 6. In brief, they may call member functions, but calling a pure virtual function in the constructor is undefined behavior. Don't do that.
If you have a class as shown in your post, which takes an XElement in the constructor, then the only place that XElement could have come from is the derived class. So why not just load the state in the derived class which already has the XElement.
Either your example is missing some fundamental information which changes the situation, or there's simply no need to chain back up to the derived class with the information from the base class, because it has just told you that exact information.
i.e.
public class BaseClass
{
public BaseClass(XElement defintion)
{
// base class loads state here
}
}
public class DerivedClass : BaseClass
{
public DerivedClass (XElement defintion)
: base(definition)
{
// derived class loads state here
}
}
Then your code's really simple, and you don't have any of the virtual method call problems.
For C++, read Scott Meyer's corresponding article :
Never Call Virtual Functions during Construction or Destruction
ps: pay attention to this exception in the article:
The problem would almost certainly
become apparent before runtime,
because the logTransaction function is
pure virtual in Transaction. Unless it
had been defined (unlikely, but
possible) the program wouldn't link: the linker would be unable to find the necessary implementation of Transaction::logTransaction.
Usually you can get around these issues by having a greedier base constructor. In your example, you're passing an XElement to LoadState. If you allow the state to be directly set in your base constructor, then your child class can parse the XElement prior to calling your constructor.
public abstract class BaseObject {
public BaseObject(int state1, string state2, /* blah, blah */) {
this.State1 = state1;
this.State2 = state2;
/* blah, blah */
}
}
public class ChildObject : BaseObject {
public ChildObject(XElement definition) :
base(int.Parse(definition["state1"]), definition["state2"], /* blah, blah */) {
}
}
If the child class needs to do a good bit of work, it can offload to a static method.
In C++ it is perfectly safe to call virtual functions from within the base-class - as long as they are non-pure - with some restrictions. However, you shouldn't do it. Better initialize objects using non-virtual functions, which are explicitly marked as being such initialization functions using comments and an appropriate name (like initialize). If it is even declared as pure-virtual in the class calling it, the behavior is undefined.
The version that's called is the one of the class calling it from within the constructor, and not some overrider in some derived class. This hasn't got much to-do with virtual function tables, but more with the fact that the override of that function might belong to a class that's not yet initialized. So this is forbidden.
In C# and Java, that's not a problem, because there is no such thing as a default-initialization that's done just before entering the constructor's body. In C#, the only things that are done outside the body is calling base-class or sibling constructors i believe. In C++, however, initializations done to members of derived classes by the overrider of that function would be undone when constructing those members while processing the constructor initializer list just before entering the constructors body of the derived class.
Edit: Because of a comment, i think a bit of clarification is needed. Here's an (contrived) example, let's assume it would be allowed to call virtuals, and the call would result in an activation of the final overrider:
struct base {
base() { init(); }
virtual void init() = 0;
};
struct derived : base {
derived() {
// we would expect str to be "called it", but actually the
// default constructor of it initialized it to an empty string
}
virtual void init() {
// note, str not yet constructed, but we can't know this, because
// we could have called from derived's constructors body too
str = "called it";
}
private:
string str;
};
That problem can indeed be solved by changing the C++ Standard and allowing it - adjusting the definition of constructors, object lifetime and whatnot. Rules would have to be made to define what str = ...; means for a not-yet constructed object. And note how the effect of it then depends on who called init. The feature we get does not justify the problems we have to solve then. So C++ simply forbids dynamic dispatch while the object is being constructed.