Why can't static methods be abstract in Java?
Asked Answered
I

30

672

The question is in Java why can't I define an abstract static method? for example

abstract class foo {
    abstract void bar( ); // <-- this is ok
    abstract static void bar2(); //<-- this isn't why?
}
Inoperative answered 16/12, 2008 at 10:45 Comment(2)
Few reasons: static method must have a body even if they are part of abstract class because one doesn't need to create instance of a class to access its static method. Another way to think about it is if for a moment we assume it is allowed then the problem is that static method calls don't provide any Run Time Type Information (RTTI), remember no instance creation is required, thus they can't redirected to their specific overriden implementations and thus allowing abstarct static makes no sense at all. In other words, it couldn't provides any polymorphism benefit thus not allowed.Meza
This question was asked about 15 years ago. Isn't there a way to use (popper) Annotations (at pre-compile time) to harshly indicate that a static method in an abstract class should be overridden?Fusiform
H
100

The abstract annotation to a method indicates that the method MUST be overriden in a subclass.

In Java, a static member (method or field) cannot be overridden by subclasses (this is not necessarily true in other object oriented languages, see SmallTalk.) A static member may be hidden, but that is fundamentally different than overridden.

Since static members cannot be overriden in a subclass, the abstract annotation cannot be applied to them.

As an aside - other languages do support static inheritance, just like instance inheritance. From a syntax perspective, those languages usually require the class name to be included in the statement. For example, in Java, assuming you are writing code in ClassA, these are equivalent statements (if methodA() is a static method, and there is no instance method with the same signature):

ClassA.methodA();

and

methodA();

In SmallTalk, the class name is not optional, so the syntax is (note that SmallTalk does not use the . to separate the "subject" and the "verb", but instead uses it as the statemend terminator):

ClassA methodA.

Because the class name is always required, the correct "version" of the method can always be determined by traversing the class hierarchy. For what it's worth, I do occasionally miss static inheritance, and was bitten by the lack of static inheritance in Java when I first started with it. Additionally, SmallTalk is duck-typed (and thus doesn't support program-by-contract.) Thus, it has no abstract modifier for class members.

Hyperform answered 16/12, 2008 at 20:17 Comment(6)
"A static member cannot be overridden by subclasses" is wrong. It is possible, at least in Java6. Not sure since when it is the case.Empathy
@Steven De Groote A static member indeed cannot be overridden by subclasses. If a subclass has a static method with the same signature as a static method in the superclass, it doesn't override it, it hides it. http://docs.oracle.com/javase/tutorial/java/IandI/override.html The difference is that polymorphism works only for overridden, but not for hidden methods.Odrick
@Odrick Thanks for the clarification, but apart from the naming difference it seems similar in usage.Empathy
@Steven De Groote Yes, it's similar in usage, but the behavior is different. That's the reason why there're no static abstract methods - what's the point of static abstract methods if they don't support polymorphism?Odrick
@Steven De Groote: The difference becomes apparent when you have a call to that method in the superclass itself. Suppose Super.foo calls Super.bar. If a subclass implements Subclass.bar, and then calls foo, then foo will still call Super.bar, not Subclass.bar. Hence, what you really have is two entirely different and unrelated methods both called "bar". This is not overriding in any useful sense.Hydrodynamics
I regard this as a limitation (in year 2023). I need an Operation abstract class and several operations as subclasses, each has static newReq() and newRsp(), but I cannot claim abstract static newReq() or newRsp() in class Operation.Frecklefaced
W
599

Because "abstract" means: "Implements no functionality", and "static" means: "There is functionality even if you don't have an object instance". And that's a logical contradiction.

Warmth answered 16/12, 2008 at 10:50 Comment(27)
A more concise answer would be 'bad language design.' Static should mean 'belongs to the class' because that's how it's used intuitively as this very question demonstrates. See "classmethod" in Python.Bide
@Alexander: This is question not about static, but about abstract static. Static means "beongs to the class" in Java as well.Warmth
@Warmth I apologize, I was not clear. Of course a static method 'belongs to the class'. Still, it is only in the sense that it lives in the same namespace. A static method is not a method of the class object itself: it does not operate with 'this' as the class object, and it does not participate properly in the chain of inheritance. If it truly was a class method abstract static would make perfect sense. It'd be a method of the class object itself which subclass objects must implement. Of course, the way things stands your answer is correct despite my griping about the language.Bide
It's not a logical contradiction, it's a language shortcoming, multiple other languages support this notion. "abstract" mean "implemented in subclasses", "static" means "executed on the class rather than class instances" There is no logical contradiction.Pericycle
@Eric: And still, what you say does not apply to abstract static: A function X that is "implemented in the subclass" cannot at the same time be "executed on the class" - only on the subclass. Where it then is not abstract anymore.Warmth
I agree with @Eric. To be a logical contradiction, the logic would need to originate from outside the rules of java. It may be true that in java, static means "functionality, even without an object instance" but this does not contradict abstract except by the design of the language. int means 'one integer' and [] means 'an array' but the fact that Java knows what I want from int[] doesn't mean it is contradicting itself, but rather that the human writers of java decided to allow for a certain functionality tied to a particular arrangement of grammar.Coriss
@uncheck: I understand that the two things (abstract and static) are separate, even orthogonal. Yet a method that is declared as both does not make a lot of sense. Either it is abstract (i.e. empty and to be implemented in a child class) or it's static (i.e. not empty and callable on the class itself). Maybe you could explain to me how it can logically be both at the same time.Warmth
@Tomakak: Your logic is circular. static doesn't mean "not empty" -- that's just a consequence of Java not allowing static methods to be abstract. It means "callable on the class." (It should mean "callable only on the class" but that's another issue.) If Java supported abstract static methods I'd expect it to mean that the method 1) must be implemented by subclasses, and 2) is a class method of the subclass. Some methods just don't make sense as instance methods. Unfortunately Java doesn't let you specify that when creating an abstract base class (or an interface).Deaconess
@Warmth a clear problem I'm experiencing right now is when you have to know the class of the child object when in an inherited constructor (deep Exception hierarchy): as it is an information belonging to the class, you have to make this method static, but as you can not inherit static methods, you would need to make it abstract in some way; you could use a non-static method, but the problem is that non static methods are not callable in a constructor; so you just can't know the type of your instanciated object in an inherited constructor, unless you give it as an argument ! It's just silly.Heinrik
I agree with Alexander, but one way to do this is to define a static method, have it call the implementation of a singleton instance of the same class. Then that method could be overriden by having the singleton exchanged with another subclass implementation...Burrill
As with many things in Java, coming from another language it seems like a limitation, but later you realize it is something you shouldn't do anyway. For example, in Leo's comment, if you need to know the child class in the inherited constructor, that is a blatant violation of basic OOP principles. Also, how do you propose such a method would be invoked? To invoke a static method you need the class name. Using the base class name, how do you know what subclass you intended? Yet if do you know the subclass, it didn't need to be abstract to begin with. Show syntax how this would even work.Kaleighkalends
If there even were a way to invoke it, how would you know if the abstract method was implemented? A class must implement all abstract methods before it can be instantiated, but for a static method, you DON'T instantiate the class. So how do you know in the first place if it is even a valid call? In Delphi, for example, you can create static abstract methods, but you can also get exceptions at runtime when you call such a method. I prefer a compile time error to a runtime error always. Like I said, it seems limiting coming from another language, but Java is trying to help you with good design.Kaleighkalends
Then why in the docs it is stated: "An abstract class may have static fields and static method" while here it cant have one?Sorel
Features such as abstract static methods have a tendency to drive poor design. The whole purpose of an abstract method is to allow patterns such as method factory, template method, etc. These are good design patterns when used correctly, and are available due to the polymorphism quality of OO languages. An abstract static method on the other hand, has no power other than to force subclasses to implement something, which is a clear violation of several OO design principles (e.g. OCP).Commute
This seems like a poor 'feature' to me. I could still subclass a class and wish to override the static methods on that class. This way forces me to instantiate a class just to override methods that could otherwise be declared static if those methods don't mutate or use instance state.Statecraft
-1, need more downvotes. static does not mean "functionality exists without object instance". static means "functionality may exist without object instance". In the case when it's both static and abstract, functionality will not exist in the parent class but will be implemented in its subclass.Theotokos
@ChadNB, As with many things in Java, coming from Java it seems like the right thing, but later you realize it is something merely an arbitrary language limitation. Abstract static can exist in strongly-typed languages like Java, it will not give runtime exceptions...............Theotokos
.................Consider a static abstract method T1 Parent.F1(T2 x) There will be no runtime exception when we call it's subclass implementation T1 Child.F1(T2 x), so why do you say that we will have runtime exceptions? Also, the whole point of abstract method is that you don't have to know whether it's implemented or not. The subclass class will implement it and the subclass will guarantee that the Liskov contract T1 Parent.F1(T2 x) is kept. If there is no subclass, there's no worry anyway since an abstract method can only be called on a subclass.Theotokos
I once had a class A with a static main(String[] args) method, and a B class with also a static main(String[] args) throws Exception. And that resulted into a compiler error: could not override method.Catanzaro
@Theotokos Think through it. How do you call it? Three ways: (1) Using the subclass name directly, as Child.Method - but in this case it didn't need to be abstract because you're referring to a specific subclass name anyway; (2) through an object - but then it didn't need to be static; (3) through a Class<?> instance with reflection - but then the compiler can't guarantee that the Class instance has the method defined, and now you're subject to runtime exception if you call an abstract method when you were reflecting Parent. Bottom line: needing static abstract indicates a design flawKaleighkalends
@ChadNB, You're almost there. A few more steps and you'll see the light. I shall guide you: Your second option is the correct one. It will be called through the object instance e.g. obj_child.StaticF(). So your experience with Java made you think "but then it didn't need to be static"; and the response we give is "but then it didn't need to be non static." Static is the default option for methods. Only methods that reference object instances should be declared non static. For example, if we .................................................................................Theotokos
..............................................................................have a method f(){ return "hello world"; }, it should be static because there is no referenced object instance. But if we have a method f(){ return "hello world " + this.Name; }, then it should be non-static, because there is an object instance being referenced. Static should always the default option. In Java, we are forced to declare static methods as non-static because static inheritance is broken in Java. It's a language shortcoming as Eric stated.Theotokos
@Theotokos On what theoretical grounds is static the "default"? It sounds like you just made that up. Perhaps in procedural programming; in OOP actually I would argue instance methods are the default. Anyway, why? If you are calling on an instance, why are you so concerned that it be static? How does that make any practical difference?Kaleighkalends
@ChadNB, Perhaps I should break the explanation up into steps. Consider this method f(){ return "hello world"; }. You have two choices. 1) Make it static. 2) Make it non-static. Which will you choose and which do you think is the default?Theotokos
@Theotokos Making it static in the parent is less flexible because it means subclasses will never be allowed to use their instance fields. Non-static is a more extensible, reusable design. I only make it static if I need the convenience of calling it without an instance, usually utility methods. If I were only planning to call the method against an instance as in the scenario you presented, I would make it non-static. An instance method is more flexible even if the language did support polymorphism of static methods because it does not add unnecessary constraints on subclasses.Kaleighkalends
@ChadNB, It's not an unnecessary constraint, but a necessary one if you care about beautiful code and design. It's an ugly hack to declare an intrinsically static function like f(){ return "hello world"; } as nonstatic because by doing so, you unnecessarily coupled it together with the this variable. The kind of "flexibility" you are citing is a violation of low coupling. It's as bad as the "flexibility" you gain by declaring all fields and methods as public.Theotokos
Be that as it may, what if I want to declare a class method in an abstract class that I want subclasses to implement?Cofferdam
C
391

Poor language design. It would be much more effective to call directly a static abstract method than creating an instance just for using that abstract method. Especially true when using an abstract class as a workaround for enum inability to extend, which is another poor design example. Hope they solve those limitations in a next release.

Coeliac answered 20/10, 2009 at 14:27 Comment(7)
Java is full of strange limitations. Closures accessing only final variables is another. And the remaining list is almost endless. It is the job of a Java programmer to know them and their workarounds. In order to have fun we have to use something better than Java in our spare time. But I would not bother about. That is the seed to achieve progress.Murdoch
I believe that what you refer to as "Poor language design" is really more of a "Protective language design", which purpose is to limit the OO principle violations that programers do due to unnecessary language features.Commute
Is the concept of "abstract static" a violation of OO principles?Neuropathy
@threed, Not at all, but of course there are folks who say that the mere concept of static itself is already a violation....Theotokos
The need for static is a clear demonstration that "OO principles" are not as all-encompassing as usually claimed.Crossways
@Crossways There is no absolute need for statics. And many OO purists will tell you that statics are an abomination.Ferryboat
C++ is full of the same limitation.Missie
I
153

You can't override a static method, so making it abstract would be meaningless. Moreover, a static method in an abstract class would belong to that class, and not the overriding class, so couldn't be used anyway.

Imbibition answered 16/12, 2008 at 10:48 Comment(8)
Yes it is really a shame by the way that static methods cannot be overridden in Java.Yuk
@Michel: what would be the point? If you want instance based behavior, use instance methods.Candleberry
This answer is incorrect. Static methods in abstract classes work fine and are commonly used. It's just that a static methods of the class itself may not be abstract. @Yuk it doesn't make sense to override a static method. Without an instance, how would the runtime know which method to invoke?Azotic
@Azotic - Even without an instance, the class hierarchy is intact - inheritance on static methods can work just like inheritance of instance methods. Smalltalk does it, and it is quite useful.Hyperform
Good news. From official docs for java 7 (see docs.oracle.com/javase/tutorial/java/IandI/abstract.html): "An abstract class may have static fields and static methods. You can use these static members with a class reference—for example, AbstractClass.staticMethod()—as you would with any other class."Unset
@Unset that's nothing new at all. Abstract classes have always been allowed to have static, non-abstract methods.Manvil
@MattBall that's true, I guess my mind added an "abstract" where it was not written. So: bad news. This is not changed in Java 7.Unset
@Unset — And this is one of many reasons we can't have nice things.Ping
H
100

The abstract annotation to a method indicates that the method MUST be overriden in a subclass.

In Java, a static member (method or field) cannot be overridden by subclasses (this is not necessarily true in other object oriented languages, see SmallTalk.) A static member may be hidden, but that is fundamentally different than overridden.

Since static members cannot be overriden in a subclass, the abstract annotation cannot be applied to them.

As an aside - other languages do support static inheritance, just like instance inheritance. From a syntax perspective, those languages usually require the class name to be included in the statement. For example, in Java, assuming you are writing code in ClassA, these are equivalent statements (if methodA() is a static method, and there is no instance method with the same signature):

ClassA.methodA();

and

methodA();

In SmallTalk, the class name is not optional, so the syntax is (note that SmallTalk does not use the . to separate the "subject" and the "verb", but instead uses it as the statemend terminator):

ClassA methodA.

Because the class name is always required, the correct "version" of the method can always be determined by traversing the class hierarchy. For what it's worth, I do occasionally miss static inheritance, and was bitten by the lack of static inheritance in Java when I first started with it. Additionally, SmallTalk is duck-typed (and thus doesn't support program-by-contract.) Thus, it has no abstract modifier for class members.

Hyperform answered 16/12, 2008 at 20:17 Comment(6)
"A static member cannot be overridden by subclasses" is wrong. It is possible, at least in Java6. Not sure since when it is the case.Empathy
@Steven De Groote A static member indeed cannot be overridden by subclasses. If a subclass has a static method with the same signature as a static method in the superclass, it doesn't override it, it hides it. http://docs.oracle.com/javase/tutorial/java/IandI/override.html The difference is that polymorphism works only for overridden, but not for hidden methods.Odrick
@Odrick Thanks for the clarification, but apart from the naming difference it seems similar in usage.Empathy
@Steven De Groote Yes, it's similar in usage, but the behavior is different. That's the reason why there're no static abstract methods - what's the point of static abstract methods if they don't support polymorphism?Odrick
@Steven De Groote: The difference becomes apparent when you have a call to that method in the superclass itself. Suppose Super.foo calls Super.bar. If a subclass implements Subclass.bar, and then calls foo, then foo will still call Super.bar, not Subclass.bar. Hence, what you really have is two entirely different and unrelated methods both called "bar". This is not overriding in any useful sense.Hydrodynamics
I regard this as a limitation (in year 2023). I need an Operation abstract class and several operations as subclasses, each has static newReq() and newRsp(), but I cannot claim abstract static newReq() or newRsp() in class Operation.Frecklefaced
D
14

I also asked the same question , here is why

Since Abstract class says, it will not give implementation and allow subclass to give it

so Subclass has to override the methods of Superclass ,

RULE NO 1 - A static method cannot be overridden

Because static members and methods are compile time elements , that is why Overloading(Compile time Polymorphism) of static methods are allowed rather then Overriding (Runtime Polymorphism)

So , they cant be Abstract .

There is no thing like abstract static <--- Not allowed in Java Universe

Dahna answered 15/5, 2013 at 7:13 Comment(3)
-1, It is not true that "Java does not allow static method to be overridden because static members and methods are compile time elements". Static type-checking is definitely possible with abstract static see #371462 . The real reason why Java does not allow static methods to be overridden is because Java does not allow static methods to be overridden.Theotokos
Overloading has nothing to do with polymorphism. Overloading and overriding have nothing in common except the prefix "over" in much the same way Java and JavaScript happen to both have "Java" in them. A method's name isn't what identities it, it's its signature that does. so foo(String) is not the same as foo(Integer) -- that's all it is.Preliminary
@CaptainMan Overloading is literally called "parametric polymorphism" because, depending on the type of the parameter, a different method gets called which is polymorphism.Sorn
B
11

This is a terrible language design and really no reason as to why it can't be possible.

In fact, here is a pattern or way on how it can be mimicked in **Java ** to allow you at least be able to modify your own implementations:

public static abstract class Request {                 

        // Static method
        public static void doSomething() {
                get().doSomethingImpl();
        }
        
        // Abstract method
        abstract void doSomethingImpl();

        /////////////////////////////////////////////
        private static Request SINGLETON;
        private static Request get() {
            if ( SINGLETON == null ) {
                // If set(request) is never called prior,
                // it will use a default implementation. 
                return SINGLETON = new RequestImplementationDefault();
            }
            return SINGLETON;
        }
        public static Request set(Request instance){
            return SINGLETON = instance;
        }
        /////////////////////////////////////////////
}

Two implementations:

/////////////////////////////////////////////////////

public static final class RequestImplementationDefault extends Request {
        @Override void doSomethingImpl() {
                System.out.println("I am doing something AAA");
        }
}

/////////////////////////////////////////////////////

public static final class RequestImplementaionTest extends Request {
        @Override void doSomethingImpl() {
                System.out.println("I am doing something BBB");
        }
}

/////////////////////////////////////////////////////

Could be used as follows:

Request.set(new RequestImplementationDefault());

// Or

Request.set(new RequestImplementationTest());

// Later in the application you might use

Request.doSomething();

This would allow you to invoke your methods statically, yet be able to alter the implementation say for a Test environment.

Theoretically, you could do this on a ThreadLocal as well, and be able to set instance per Thread context instead rather than fully global as seen here, one would then be able to do Request.withRequest(anotherRequestImpl, () -> { ... }) or similar.

Real world usually do not require the ThreadLocal approach and usually it is enough to be able to alter implementation for Test environment globally.

Note, that the only purpose for this is to enable a way to retain the ability to invoke methods DIRECTLY, EASILY and CLEANLY which static methods provides while at the same time be able to switch implementation should a desire arise at the cost of slightly more complex implementation.

It is just a pattern to get around having normally non modifiable static code.

Burrill answered 19/3, 2012 at 16:54 Comment(4)
I didn't understand where you have provided an example of an abstract static method as asked in the question and you have written in bold CAN BE DONE IN JAVA. This is completely misguiding.Steapsin
It doesn't per se allow you to define it as abstract static, but you can achieve a similar result whereby you can change the implementation of s static method using this pattern/hack. It's hardly misguided. It can be done, but using different semantics.Burrill
This is an example of extending an abstract class, then putting the static methods in the child. This is not an example of CAN BE DONE IN JAVA, in any way whatsoever.Gibbon
@ScubaSteve First, you are wrong on your conclusion. Second, it achieves the same result. Meaning static access to a class can be changed by another implementation. It's not an answer as to saying I made the static keyword abstractable, but using this pattern you can could use static methods and still change their implementation. It does have the negative affect of being global only though, but for a test / prod / dev environment it does the trick for us.Burrill
R
6

A static method, by definition, doesn't need to know this. Thus, it cannot be a virtual method (that is overloaded according to dynamic subclass information available through this); instead, a static method overload is solely based on info available at compile time (this means: once you refer a static method of superclass, you call namely the superclass method, but never a subclass method).

According to this, abstract static methods would be quite useless because you will never have its reference substituted by some defined body.

Rai answered 5/12, 2015 at 13:16 Comment(0)
L
5
  • An abstract method is defined only so that it can be overridden in a subclass. However, static methods can not be overridden. Therefore, it is a compile-time error to have an abstract, static method.

    Now the next question is why static methods can not be overridden??

  • It's because static methods belongs to a particular class and not to its instance. If you try to override a static method you will not get any compilation or runtime error but compiler would just hide the static method of superclass.

Ledda answered 16/12, 2008 at 10:45 Comment(0)
L
2

Assume there are two classes, Parent and Child. Parent is abstract. The declarations are as follows:

abstract class Parent {
    abstract void run();
}

class Child extends Parent {
    void run() {}
}

This means that any instance of Parent must specify how run() is executed.

However, assume now that Parent is not abstract.

class Parent {
    static void run() {}
}

This means that Parent.run() will execute the static method.

The definition of an abstract method is "A method that is declared but not implemented", which means it doesn't return anything itself.

The definition of a static method is "A method that returns the same value for the same parameters regardless of the instance on which it is called".

An abstract method's return value will change as the instance changes. A static method will not. A static abstract method is pretty much a method where the return value is constant, but does not return anything. This is a logical contradiction.

Also, there is really not much of a reason for a static abstract method.

Leuco answered 14/6, 2015 at 21:11 Comment(0)
H
2

An abstract class cannot have a static method because abstraction is done to achieve DYNAMIC BINDING while static methods are statically binded to their functionality.A static method means behavior not dependent on an instance variable, so no instance/object is required.Just the class.Static methods belongs to class and not object. They are stored in a memory area known as PERMGEN from where it is shared with every object. Methods in abstract class are dynamically binded to their functionality.

Heeling answered 17/7, 2015 at 16:12 Comment(2)
Abstract classes can surely have static methods. But not static abstract methods.Heraldry
Then pls can Java add a new keyword, for dynamically binded methods that belong to the class and not the instance.Tommi
B
2

I see that there are a god-zillion answers already but I don't see any practical solutions. Of course this is a real problem and there is no good reason for excluding this syntax in Java. Since the original question lacks a context where this may be need, I provide both a context and a solution:

Suppose you have a static method in a bunch of classes that are identical. These methods call a static method that is class specific:

class C1 {
    static void doWork() {
        ...
        for (int k: list)
            doMoreWork(k);
        ...
    }
    private static void doMoreWork(int k) {
        // code specific to class C1
    }
}
class C2 {
    static void doWork() {
        ...
        for (int k: list)
            doMoreWork(k);
        ...
    }
    private static void doMoreWork(int k) {
        // code specific to class C2
    }
}

doWork() methods in C1 and C2 are identical. There may be a lot of these calsses: C3 C4 etc. If static abstract was allowed, you'd eliminate the duplicate code by doing something like:

abstract class C {
    static void doWork() {
        ...
        for (int k: list)
            doMoreWork(k);
        ...
    }

    static abstract void doMoreWork(int k);
}

class C1 extends C {
    private static void doMoreWork(int k) {
        // code for class C1
    }
}

class C2 extends C {
    private static void doMoreWork(int k) {
        // code for class C2
    }
}

but this would not compile because static abstract combination is not allowed. However, this can be circumvented with static class construct, which is allowed:

abstract class C {
    void doWork() {
        ...
        for (int k: list)
            doMoreWork(k);
        ...
    }
    abstract void doMoreWork(int k);
}
class C1 {
    private static final C c = new  C(){  
        @Override void doMoreWork(int k) {
            System.out.println("code for C1");
        }
    };
    public static void doWork() {
        c.doWork();
    }
}
class C2 {
    private static final C c = new C() {
        @Override void doMoreWork(int k) {
            System.out.println("code for C2");
        }
    };
    public static void doWork() {
        c.doWork();
    }
}

With this solution the only code that is duplicated is

    public static void doWork() {
        c.doWork();
    }
Briefcase answered 20/1, 2016 at 13:2 Comment(2)
Since in your final solution abstract class C doesn't has any static methods then why not just let C1 and C2 extend it and override doMoreWork() method and let any other classes make its instance and call required methods. Basically you are doing the same i.e. extending class C using anonymous class and then in C1 and C2 using its static instance to allow access from within a static method but this is not required at all.Meza
I don't understand the context that you have provided here. In your final solution what you can do is call C1.doWork() or C2.doWork() But you cannot call C.doWork(). Also in the example that you have provided, which won't work, suppose if it was allowed, then how will class C find the implementation of doMoreWork()? Finally I would call your context code a bad design. Why? simply because you have created a separate function for the code that is unique instead of creating a function for the code that is common and then implementing a static function in the class C. This is easier!!!Steapsin
M
2

Declaring a method as static means we can call that method by its class name and if that class is abstract as well, it makes no sense to call it as it does not contain any body, and hence we cannot declare a method both as static and abstract.

Merrick answered 13/6, 2018 at 14:54 Comment(1)
But we want to have static methods in extending classes. For instance, write a name of the class instead of getSimpleName(). We want to have abstract static String getClassName(); and extend it in all child classes.Lat
E
2

As abstract methods belong to the class and cannot be overridden by the implementing class.Even if there is a static method with same signature , it hides the method ,does not override it. So it is immaterial to declare the abstract method as static as it will never get the body.Thus, compile time error.

Excoriation answered 31/12, 2019 at 8:6 Comment(0)
H
1

A static method can be called without an instance of the class. In your example you can call foo.bar2(), but not foo.bar(), because for bar you need an instance. Following code would work:

foo var = new ImplementsFoo();
var.bar();

If you call a static method, it will be executed always the same code. In the above example, even if you redefine bar2 in ImplementsFoo, a call to var.bar2() would execute foo.bar2().

If bar2 now has no implementation (that's what abstract means), you can call a method without implementation. That's very harmful.

Halstead answered 16/12, 2008 at 11:11 Comment(2)
And an abstract static method could be called without an instance, but it would require an implementation to be created in the child class. It's not exactly polymorphism, but the only way to get around it is to have the concrete child implement an interface that "requires" the "abstract static" method. Messy, but workable.Nephron
actually, I was wrong. You can't have static methods in an interface either. Language flaw.Nephron
G
1

I believe I have found the answer to this question, in the form of why an interface's methods (which work like abstract methods in a parent class) can't be static. Here is the full answer (not mine)

Basically static methods can be bound at compile time, since to call them you need to specify a class. This is different than instance methods, for which the class of the reference from which you're calling the method may be unknown at compile time (thus which code block is called can only be determined at runtime).

If you're calling a static method, you already know the class where it's implemented, or any direct subclasses of it. If you define

abstract class Foo {
    abstract static void bar();
}

class Foo2 {
    @Override
    static void bar() {}
}

Then any Foo.bar(); call is obviously illegal, and you will always use Foo2.bar();.

With this in mind, the only purpose of a static abstract method would be to enforce subclasses to implement such a method. You might initially think this is VERY wrong, but if you have a generic type parameter <E extends MySuperClass> it would be nice to guarantee via interface that E can .doSomething(). Keep in mind that due to type erasure generics only exist at compile time.

So, would it be useful? Yes, and maybe that is why Java 8 is allowing static methods in interfaces (though only with a default implementation). Why not abstract static methods with a default implementation in classes? Simply because an abstract method with a default implementation is actually a concrete method.

Why not abstract/interface static methods with no default implementation? Apparently, merely because of the way Java identifies which code block it has to execute (first part of my answer).

Gunderson answered 29/8, 2015 at 1:25 Comment(0)
R
1

Because abstract class is an OOPS concept and static members are not the part of OOPS....
Now the thing is we can declare static complete methods in interface and we can execute interface by declaring main method inside an interface

interface Demo 
{
  public static void main(String [] args) {
     System.out.println("I am from interface");
  }
}
Riccardo answered 29/11, 2018 at 7:12 Comment(0)
S
1

Because abstract mehods always need implementation by subclass.But if you make any method to static then overriding is not possible for this method

Example

abstract class foo {
    abstract static void bar2(); 
}


class Bar extends foo {
    //in this if you override foo class static method then it will give error
}
Stallings answered 28/12, 2020 at 9:0 Comment(0)
C
1

Static Method A static method can be invoked without the need for creating an instance of a class.A static method belongs to the class rather than the object of a class. A static method can access static data member and also it can change the value of it. Abstract Keyword is used to implement abstraction. A static method can't be overriden or implemented in child class. So, there is no use of making static method as abstract.

Cruciferous answered 24/10, 2021 at 15:50 Comment(1)
Yes, there is. Imagine that you have a Processor for Responses. You define ResponseA, ResponseB, ResponseC. Each Response type as an associated Builder (inner class), to get it you have a static method "builder()". The Processor reads data and needs to use one of the Builder to obtain an instance of Response. So, in Response, you want to enforce that each subclass of Response has a method builder(). So builder() must be abstract and ideally, should be static as well. But in Java it is not possible. Another example: abstract class Shape, having abstract static boolean hasCorners() method.Benedick
C
0

The idea of having an abstract static method would be that you can't use that particular abstract class directly for that method, but only the first derivative would be allowed to implement that static method (or for generics: the actual class of the generic you use).

That way, you could create for example a sortableObject abstract class or even interface with (auto-)abstract static methods, which defines the parameters of sort options:

public interface SortableObject {
    public [abstract] static String [] getSortableTypes();
    public String getSortableValueByType(String type);
}

Now you can define a sortable object that can be sorted by the main types which are the same for all these objects:

public class MyDataObject implements SortableObject {
    final static String [] SORT_TYPES = {
        "Name","Date of Birth"
    }
    static long newDataIndex = 0L ;

    String fullName ;
    String sortableDate ;
    long dataIndex = -1L ;
    public MyDataObject(String name, int year, int month, int day) {
        if(name == null || name.length() == 0) throw new IllegalArgumentException("Null/empty name not allowed.");
        if(!validateDate(year,month,day)) throw new IllegalArgumentException("Date parameters do not compose a legal date.");
        this.fullName = name ;
        this.sortableDate = MyUtils.createSortableDate(year,month,day);
        this.dataIndex = MyDataObject.newDataIndex++ ;
    }
    public String toString() {
        return ""+this.dataIndex+". "this.fullName+" ("+this.sortableDate+")";
    }

    // override SortableObject 
    public static String [] getSortableTypes() { return SORT_TYPES ; }
    public String getSortableValueByType(String type) {
        int index = MyUtils.getStringArrayIndex(SORT_TYPES, type);
        switch(index) {
             case 0: return this.name ;
             case 1: return this.sortableDate ;
        }
        return toString(); // in the order they were created when compared
    }
}

Now you can create a

public class SortableList<T extends SortableObject> 

that can retrieve the types, build a pop-up menu to select a type to sort on and resort the list by getting the data from that type, as well as hainv an add function that, when a sort type has been selected, can auto-sort new items in. Note that the instance of SortableList can directly access the static method of "T":

String [] MenuItems = T.getSortableTypes();

The problem with having to use an instance is that the SortableList may not have items yet, but already need to provide the preferred sorting.

Cheerio, Olaf.

Coblenz answered 30/11, 2013 at 21:10 Comment(0)
R
0

First, a key point about abstract classes - An abstract class cannot be instantiated (see wiki). So, you can't create any instance of an abstract class.

Now, the way java deals with static methods is by sharing the method with all the instances of that class.

So, If you can't instantiate a class, that class can't have abstract static methods since an abstract method begs to be extended.

Boom.

Ru answered 24/7, 2014 at 15:0 Comment(1)
Every method in an abstract class needs its class to be extended anyway to be executed, so this isn't an excuse. You could extend the abstract class (at the same time, implementing the abstract method). So this doesn't work as an explanation.Maturate
T
0

As per Java doc:

A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods

In Java 8, along with default methods static methods are also allowed in an interface. This makes it easier for us to organize helper methods in our libraries. We can keep static methods specific to an interface in the same interface rather than in a separate class.

A nice example of this is:

list.sort(ordering);

instead of

Collections.sort(list, ordering);

Another example of using static methods is also given in doc itself:

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}
Tavis answered 22/6, 2015 at 4:56 Comment(0)
D
0

Because 'abstract' means the method is meant to be overridden and one can't override 'static' methods.

Diao answered 28/9, 2015 at 4:37 Comment(5)
This answer adds nothing that the previous answers haven't already addressed.Eyeshade
@Eyeshade I think it's more appropriate then the top voted answer. Also , it's succinct.Diao
Then you can edit earlier answers to improve them when you have sufficient rep. All you're doing is adding noise to the signal by creating duplicate answers. Please follow Stack Overflow's established rules and customs rather than creating your own and expecting everyone else to follow.Eyeshade
I disagree , please compare my answer to other , especially the top voted answer.Diao
"Why can't I do this?" Answer: "because you can't".Heraldry
Q
0

Regular methods can be abstract when they are meant to be overridden by subclasses and provided with functionality. Imagine the class Foo is extended by Bar1, Bar2, Bar3 etc. So, each will have their own version of the abstract class according to their needs.

Now, static methods by definition belong to the class, they have nothing to do with the objects of the class or the objects of its subclasses. They don't even need them to exist, they can be used without instantiating the classes. Hence, they need to be ready-to-go and cannot depend on the subclasses to add functionality to them.

Q answered 5/12, 2015 at 11:46 Comment(0)
G
0

Because abstract is a keyword which is applied over Abstract methods do not specify a body. And If we talk about static keyword it belongs to class area.

Gal answered 13/5, 2017 at 12:11 Comment(1)
please be a little bit elaborate about your answer.Steapsin
N
0

because if you are using any static member or static variable in class it will load at class loading time.

Nonagenarian answered 9/3, 2018 at 6:49 Comment(1)
and why would that be an issue?Pachton
D
0

There is one occurrence where static and abstract can be used together and that is when both of these modifiers are placed in front of a nested class.

Desiraedesire answered 18/8, 2021 at 4:35 Comment(0)
M
0

In a single line, this dangerous combination (abstract + static) violates the object-oriented principle which is Polymorphism.

In an inheritance situation, the JVM will decide at runtime by the implementation in respect of the type of instance (runtime polymorphism) and not in respect of the type of reference variable (compile-time polymorphism).

With @Overriding:

enter image description here

Static methods do not support @overriding (runtime polymorphism), but only method hiding (compile-time polymorphism).

With @Hiding:

enter image description here

But in a situation of abstract static methods, the parent (abstract) class does not have implementation for the method. Hence, the child type reference is the only one available and it is not polymorphism.

Child reference is the only one available:

enter image description here

For this reason (suppress OOPs features), Java language considers abstract + static an illegal (dangerous) combination for methods.

Malemute answered 21/4, 2022 at 0:57 Comment(1)
Suppose you have a Shape, and child classes Circle and Square. Why can't we define an abstract static hasCorners() on Shape? It's bad tha you need an instrumental dummy instance just to call hasCorners() because you can't do Circle.hasCorners() or Square.hasCorners().Benedick
B
-1

Because if a class extends an abstract class then it has to override abstract methods and that is mandatory. And since static methods are class methods resolved at compile time whereas overridden methods are instance methods resolved at runtime and following dynamic polymorphism.

Baptlsta answered 16/2, 2013 at 14:19 Comment(1)
Please capitalise and punctuate this mess.Missie
I
-1

You can do this with interfaces in Java 8.

This is the official documentation about it:

https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Intisar answered 22/3, 2014 at 19:53 Comment(3)
How? I've looked for solutions and couldn't find any.Bainbrudge
Wut? You can not. All static interfaces methods has to invoked using the interface class.Burrill
This answer is wrong and is misguiding to people new in java. This does to show any example of abstract static method as it cannot be implemented and stated in other answersSteapsin
P
-1

let me explain :

Abstract Method needs a subclass to implement it and then you call that method with that subclass instance. Example : Child inherit from Parent and implement one abstract method doSomething(). Now you will call this method in such way : Parent p = new Child(); p.doSomething(); here you can see, you need instance of subclass to get its implementation. So, basically abstract method are instance dependent.

Static method belongs to class itself. Example : if Parent class has a static method doSomething(), you will call this method on parent itself like Parent.doSomething(); So, static method has no dependency on instance.

Now, if you make static method abstract then following problem will come: Example : Child1 and Child2 inherits from Parent and implements its static abstract method doSomething(); when you call this method - Parent.doSomething(); how it will be decided which implementation to invoke(Child1 or Child2). That's why it is not allowed to have static abstract method.

Popham answered 10/3, 2023 at 5:21 Comment(2)
"how it will be decided which implementation to invoke" ? - that method will be invoked , "the instance of which is in the refence variable of Parent"....thats the point of upcasting / code to interface / polymorphism / strategy design - whatever you like to call it. But sadly Java don't allow static to be abstract ..I strongly feel it must allow bcoz : I might like each implementing class to have a static method of same signature but different logic inside and hence I want to force its signature in parent interface - how about that ?Keos
eg. when p = new Child1(); p.doSomething() calls new Child1().doSomething(); when p = new Child2(); p.doSomething() calls new Child2().doSomething(); one might argue then whats the point if we dont call in static way like Child1.doSomething() or Child2.doSomething() ...the point is : its not always about "static way" but sometimes the need of "one per class"Keos

© 2022 - 2024 — McMap. All rights reserved.