This is a strange question but I was wondering if there was a way to "override" a parent class's static method in a subclass and call that subclass's static method from the parent class.
It would look something like this
public class parentFoo {
public static void <T extends parentFoo> printFoo () {
T.printFoo();
}
}
public class childFoo extends parentFoo {
public static void printFoo() {
System.out.println("Foo");
}
}
so you could do something like this in your code
//print out "Foo"
parentFoo.<childFoo>printFoo();
This isn't working for me but I was wondering if there is some way to make this possible. Right now I get a stack overflow because it only calls the parent class's printFoo method.
You cannot override static methods. You can however define static methods of the same name. If you do that then you can specify which one is called from the class type
ChildFoo.printFoo(); // call child foo
ParentFoo.printFoo(); // call parent foo
ParentFoo foo1 = new ChildFoo();
foo1.printFoo(); // ParentFoo still called because of type of reference foo1 not its value
ChildFoo foo2 = new ChildFoo();
foo2.printFoo(); // ChildFoo called because of type of reference foo2 not its value
There's no way to to call a static method based on a generic type parameter.
The answer to the question below provides a reasonable workaround.
Calling a static method using generic type
Replace
parentFoo.<childFoo>printFoo();
with
childFoo.printFoo();
Why would you need to override static methods? (which isn't possible) What are you trying to accomplish?
A polymorphic call only makes sense for objects. Since statics aren't part of an object, but of a class, it doesn't.
Related
I'd like to know:
Why can't static methods be overridden in Java?
Can static methods be overloaded in Java?
Static methods can not be overridden in the exact sense of the word, but they can hide parent static methods
In practice it means that the compiler will decide which method to execute at the compile time, and not at the runtime, as it does with overridden instance methods.
For a neat example have a look here.
And this is java documentation explaining the difference between overriding instance methods and hiding class (static) methods.
Overriding: 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)
Hiding: Parent class methods that are static are not part of a child class (although they are accessible), so there is no question of
overriding it. Even if you add another static method in a subclass,
identical to the one in its parent class, this subclass static method
is unique and distinct from the static method in its parent class.
Static methods can not be overridden because there is nothing to override, as they would be two different methods. For example
static class Class1 {
public static int Method1(){
return 0;
}
}
static class Class2 extends Class1 {
public static int Method1(){
return 1;
}
}
public static class Main {
public static void main(String[] args){
//Must explicitly chose Method1 from Class1 or Class2
Class1.Method1();
Class2.Method1();
}
}
And yes static methods can be overloaded just like any other method.
Static methods cannot be overridden because they are not dispatched on the object instance at runtime. The compiler decides which method gets called.
This is why you get a compiler warning when you write
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod()
// because it is not dispatched on myObject
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
Static methods can be overloaded (meaning that you can have the same method name for several methods as long as they have different parameter types).
Integer.parseInt("10");
Integer.parseInt("AA", 16);
Parent class methods that are static are not part of a child class (although they are accessible), so there is no question of overriding it. Even if you add another static method in a subclass, identical to the one in its parent class, this subclass static method is unique and distinct from the static method in its parent class.
Static methods can not be overridden because they are not part of the object's state. Rather, they belongs to the class (i.e they are class methods). It is ok to overload static (and final) methods.
Overloading is also called static binding, so as soon as the word static is used it means a static method cannot show run-time polymorphism.
We cannot override a static method but presence of different implementations of the same static method in a super class and its sub class is valid. Its just that the derived class will hide the implementations of the base class.
For static methods, the method call depends on the type of reference and not which object is being referred, i.e. Static method belongs only to a class and not its instances , so the method call is decided at the compile time itself.
Whereas in case of method overloading static methods can be overloaded iff they have diff number or types of parameters. If two methods have the same name and the same parameter list then they cannot be defined different only by using the 'static' keyword.
If I m calling the method by using SubClass name MysubClass then subclass method display what it means static method can be overridden or not
class MyClass {
static void myStaticMethod() {
System.out.println("Im in sta1");
}
}
class MySubClass extends MyClass {
static void myStaticMethod() {
System.out.println("Im in sta123");
}
}
public class My {
public static void main(String arg[]) {
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod();
// calling from subclass name
MySubClass.myStaticMethod();
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
}
}
No,Static methods can't be overriden as it is part of a class rather than an object.
But one can overload static method.
Static methods are a method whose single copy is shared by all the objects of the class. A static method belongs to the class rather than objects. since static methods are not dependent on the objects, Java Compiler need not wait till the creation of the objects so to call a static method we use syntax like ClassName.method() ;
In the case of method overloading, methods should be in the same class to overload.even if they are declared as static it is possible to overload them as,
Class Sample
{
static int calculate(int a,int b,int c)
{
int res = a+b+c;
return res;
}
static int calculate(int a,int b)
{
int res = a*b;
return res;
}
}
class Test
{
public static void main(String []args)
{
int res = Sample.calculate(10,20,30);
}
}
But in the case of method overriding, the method in the super class and the method in the sub class act as a different method. the super class will have its own copy and the sub class will have its own copy so it does not come under method overriding.
class SuperType {
public static void classMethod(){
System.out.println("Super type class method");
}
public void instancemethod(){
System.out.println("Super Type instance method");
}
}
public class SubType extends SuperType{
public static void classMethod(){
System.out.println("Sub type class method");
}
public void instancemethod(){
System.out.println("Sub Type instance method");
}
public static void main(String args[]){
SubType s=new SubType();
SuperType su=s;
SuperType.classMethod();// Prints.....Super type class method
su.classMethod(); //Prints.....Super type class method
SubType.classMethod(); //Prints.....Sub type class method
}
}
This example for static method overriding
Note: if we call a static method with object reference, then reference type(class) static method will be called, not object class static method.
Static method belongs to class only.
static methods are class level methods.
Hiding concept is used for static methods.
See : http://www.coderanch.com/how-to/java/OverridingVsHiding
The very purpose of using the static method is to access the method of a class without creating an instance for it.It will make no sense if we override that method since they will be accessed by classname.method()
No, you cannot override a static method. The static resolves against the class, not the instance.
public class Parent {
public static String getCName() {
return "I am the parent";
}
}
public class Child extends Parent {
public static String getCName() {
return "I am the child";
}
}
Each class has a static method getCName(). When you call on the Class name it behaves as you would expect and each returns the expected value.
#Test
public void testGetCNameOnClass() {
assertThat(Parent.getCName(), is("I am the parent"));
assertThat(Child.getCName(), is("I am the child"));
}
No surprises in this unit test. But this is not overriding.This declaring something that has a name collision.
If we try to reach the static from an instance of the class (not a good practice), then it really shows:
private Parent cp = new Child();
`enter code here`
assertThat(cp.getCName(), is("I am the parent"));
Even though cp is a Child, the static is resolved through the declared type, Parent, instead of the actual type of the object. For non-statics, this is resolved correctly because a non-static method can override a method of its parent.
You can overload a static method but you can't override a static method. Actually you can rewrite a static method in subclasses but this is not called a override because override should be related to polymorphism and dynamic binding. The static method belongs to the class so has nothing to do with those concepts. The rewrite of static method is more like a shadowing.
I design a code of static method overriding.I think It is override easily.Please clear me how its unable to override static members.Here is my code-
class Class1 {
public static int Method1(){
System.out.println("true");
return 0;
}
}
class Class2 extends Class1 {
public static int Method1(){
System.out.println("false");
return 1;
}
}
public class Mai {
public static void main(String[] args){
Class2 c=new Class2();
//Must explicitly chose Method1 from Class1 or Class2
//Class1.Method1();
c.Method1();
}
}
It’s actually pretty simple to understand – Everything that is marked static belongs to the class only, for example static method cannot be inherited in the sub class because they belong to the class in which they have been declared. Refer static keyword.
The best answer i found of this question is:
http://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
As any static method is part of class not instance so it is not possible to override static method
From Why doesn't Java allow overriding of static methods?
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 have the benefit of familiarity for C++ programmers and were also very fast because there's no need to wait until runtime to figure out which method to call.
Definitely, we cannot override static methods in Java.
Because JVM resolves correct overridden method based upon the object at run-time by using dynamic binding in Java.
However, the static method in Java is associated with Class rather than the object and resolved and bonded during compile time.
class Base {
public static void staticMethod(Base bObj) {
System.out.println("In Base.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Base.instanceMethod()");
}
}
class Derived extends Base {
public static void staticMethod(Base bObj) {
System.out.println("In Derived.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Derived.instanceMethod()");
}
}
public class Main {
public static void main(String []args) {
Base bObj = new Derived();
bObj.staticMethod(bObj);
}
}
Initially, when I saw this example I was sure that the result would be:
"In Base.staticMethod()"
"In Base.instanceMethod()".
After the initialization of the first Derived object it is obvious that it will be interpreted as a Base object due to upcast and it will call the static method of the base class which it does but later when it calls the other method(instance method) it goes inside the derived function instead of base class.
Why, considering that initially it was considered being Base?
There is no method overriding for static methods. Therefore bObj.staticMethod(), which is equivalent to Base.staticMethod, invokes the static method of the base class.
Inside the static method you are calling bObj.instanceMethod(). For instance methods there is method overriding, and the runtime type of bObj determines which method is executed - the instance method of Derived in your case.
Override is only for instance methods. For Static Method the term is called Method Hiding See Detail.
1. If method hiding is used then BaseClass's method is hidden from Subclass. method selection solely depends on which class's reference you are using to call the method. In your example since you are using BaseClass (even you assign Subclass object, it still on the class level it's BaseClass) reference to make a call to the static method it makes a call to BaseClass's method. If you would use SubClass reference as below then it would call the SubClass's static method
public static void main(String []) {
Derived bObj = new Derived();
bObj.staticMethod(bObj);
}
As the call inside the static method is for an Instance method. It uses polymorphism here and calls the SubClass's method.
TL;DR:
bObj.staticMethod(bObj); only looks at the compile-time type of bObj, and is equivalent to Base.staticMethod(bObj); in your case. There's no overriding.
bObj.instanceMethod(); only looks at the runtime class of bObj, and selects the method based on that class. So overriding works here.
Explanation
If you call a static method, you should do so by naming the class, not an instance. So bObj.staticMethod(bObj) should better be written Base.staticMethod(bObj). Typically, the compiler will issue a warning for the first version.
That's because the runtime instance is irrevant for selecting the static method. The decision is made by the compiler. And that's why we call this method type "static", because it lacks the dynamic method lookup of instance methods. That means that there is no overriding based on the instance "before the dot".
Using an instance expression misleads the reader into thinking the instance were relevant, and therefore should not be used. And inside the static method, there is no way to refer to the instance "before the dot". The keyword this doesn't exist in static methods. To call a static method, you don't even need an instance of that class (e.g. you can't create Math instances, but you can call Math.min() without any problem).
On the other hand, if you call an instance method, you need an instance of a class having that method, and this instance gets the name this inside the method. The method selection is done at runtime, based on the runtime class of the instance, no matter what the declared type is.
As shown in http://docs.oracle.com/javase/tutorial/java/IandI/override.html, Java does allow
Overriding an instance method by an instance method and
Hiding a static method by a static method
My question is why Java doesn't allow hiding a static superclass method by an instance method. This could be done like this:
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {}
void access () {
foo ();
Base.foo ();
}
}
I don't see any particular issue with the above approach - it is only as "messy/complex" as the (allowed) hiding of statics already is.
I suspect it is to avoid confusion with dealing with the base class. In fact I imagine the designers didn't see an obvious way this should behave.
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {} // say this compiled
}
Base b = new Derived()
b.foo(); // should the static or the virtual method be called?
Should b.foo() call Base.foo() or should it potentially call Derived.foo()?
Simple answer: that would be the mess.
Concrete answer: what to call in that case Derived.foo()? Base.foo() can't be called as it's hidden (as per you), Derived.foo() can't be called as it's not static.
Because, one are like Bananas and the other ones are Apples.
Explaination:
Static Methods are created when reading the Class-Structure
Methods are created when a object of a class is created.
Example:
Foo.bar();
is something different than
new Foo().bar();
Guess which one is called?
Foo f = new Foo();
f.bar();
Another to add here is:
1. Static methods belong at the class level. So u cannot override method in the derived class.
as simple its called hiding. :)
2. Instance methods belong to the objects, so objects are overrided. So we can override in the derived class.
Above other comments give a good example have a look into it..
Regards
Punith
I have the following classes.
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
I want to access the sub-class object from a static method in super-class. i.e. When I call Sub1.useSubClass() the method has access to Sub1.class and when I use Sub2.useSubClass(), I can access the Sub2.class.
Is there any way to access the sub-class object from super-class.
In general, you cannot do that from a superclass (and shouldn't!) because you won't know (and shouldn't assume anything about!) what classes will inherit from your superclass.
Depending on exactly what you want to do, there are alternatives, such as:
Use the template pattern to define "filler methods" that your subclasses must implement; these filler methods will be called by the template method in your superclass.
Define methods to be overridden by your subclass.
Define interfaces to be implemented by your subclass.
Update: As #JB Nizet has pointed out, I might have misread the question.
Here's something (very similar to the Observer Pattern) you can do if you wish to access subclasses from the static method in your superclass:
Define a static listener list in your superclass, call it List observerList
In the constructor of your superclass, add the class instance itself to that static observerList
For all subclasses, it is their responsibility to call super() from their constructors in order to register themselves to observerList (and unregister in deconstructor)
Then in your superclass's static useSubClass() method, you can iterate through that list of subclass instances, find the particular one you care about (maybe specified by some argument), and then do something with it.
Static methods are not inherited, and calling Sub2.useSubClass() is strictly equivalent to calling Super.useSubclass().
There is no way to get this information, because it doesn't exist. The compiler allows calling Sub2.useSubclass(), but translates it into Super.useSubclass().
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
However, a better question is why? Can't you simply override the method in your subclass?
No you cannot because the super-class cannot know the methods of the sub-classes.
You should consider to create a new class which sees both super-class and sub-classes and implement the static method inside this new class
For the record, you could do this in Python, using class methods:
class super(object):
#classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
Using this code, you could call sub1.usesubclass() or sub2.usesubclass(), and that would print the representations of the sub1 and sub2 classes, respectively:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
Java, however, does not support such mechanisms, unfortunately. When you compile Sub1.useSubClass() in your example, the compiler will simply use Sub1 as the basic namespace to look up the the useSubClass() method in Super, but no information on that is actually compiled into code. In the resulting bytecode, the call is simply one directly to Super.useSubClass() and nothing more.
I sympathize with your plight, but Java is what it is. The closest thing you could come, I think, would be the following code:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
And then call that method explicitly as either Super.useSubClass(Sub1.class) or Super.useSubClass(Sub2.class).
I figured something out. It works if implemented with care.
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
This is just a toy example. The super class contains a static class that contains a method to retrieve the calling class.
In the subclass I have another static method which calls the superclass's method for printing the class name.
The Main class/function contains two calls to Sub's inherited and locally implemented method. The first call prints null, because the calling context (i.e. Main) is not a subclass of Super However the delegate method in Sub works because the calling context is now a subclass of SuperClass and hence the calling class can be determined.
Although You can create a reference to the super class and point it to any sub-class. This can also be done dynamically during run-time. This is a way of run-time polymorphism.
Say, I have a reference to a Class object with SomeType having a static method. Is there a way to call that method w/o instantiating SomeType first? Preferably not escaping strong typing.
EDIT: OK, I've screwed up.
interface Int{
void someMethod();
}
class ImplOne implements Int{
public void someMethod() {
// do something
}
}
Class<? extends Int> getInt(){
return ImplOne.class;
}
In this case someMethod() can't be static anyways.
I'm not sure exactly what the situation is, but if you're looking to execute the static method on a class without knowing the class type (i.e. you don't know it's SomeType, you just have the Class object), if you know the name and parameters of the method you could use reflection and do this:
Class c = getThisClassObjectFromSomewhere();
//myStaticMethod takes a Double and String as an argument
Method m = c.getMethod("myStaticMethod", Double.class, String.class);
Object result = m.invoke(null, 1.5, "foo");
A static method, by definition, is called on a class and not on an instance of that class.
So if you use:
SomeClass.someStaticMethod()
you are instantiating nothing (leave aside the class loading and instantiation of the SomeClass class itself, which the JVM handles and is way out of your scope).
This is opposed to a regular method called on an object, which has already been instantiated:
SomeObject o = someObject; // had to be instantiated *somewhere*
o.someMethod();
Since you talk about a Class object, I assume that you're interested in Java reflection. Here's a brief snippet that does what you're trying to do:
Class someClass = SomeType.class;
Method staticMethod = someClass.getMethod( "methodName", ... );
// pass the first arg as null to invoke a static method
staticMethod.invoke( null, ... );
Yes. That's what static methods are all about. Just call it. SomeType.yourStaticMethodHere().