Java 8 default method readability - java

Java 8 introduces the concept of default methods. Consider the following interface with a default method :
public interface IDefaultMethod {
public abstract void musImplementThisMethod();
public default void mayOrMayNotImplementThisMethod() {
System.out.println(" This method is optional for classes that implement this interface ");
}
}
And a class that implements this interface :
public class DefaultMethodImpl implements IDefaultMethod {
#Override
public void musImplementThisMethod() {
System.out.println("This method must be implementd ");
}
#Override
public void mayOrMayNotImplementThisMethod() {
// TODO Auto-generated method stub
IDefaultMethod.super.mayOrMayNotImplementThisMethod();
}
}
I have a question about the readability of the following call in the mayOrMayNotImplementThisMethod :
IDefaultMethod.super.mayOrMayNotImplementThisMethod();
I understand that the reason for explicitly specifying the interface name in the above call is to avoid confusion in case multiple interfaces implemented by the class have the same method. What I don't understand is the meaning of the super keyword in this context. When we say IDefaultMethod.super, what exactly are we referring to here? Wouldn't IDefaultMethod.mayOrMayNotImplementThisMethod() be more readable than IDefaultMethod.super.mayOrMayNotImplementThisMethod()? Removing the super keyword makes it more readable at the cost of distinguishing between a static or non static method call.

I will try to contribute to the discussion by following my own reasonings about this.
Using Classes
First, let's see how this work with simple Java classes:
class Barney {
void foo() { System.out.println("Barney says foo"); }
}
class Fred extends Barney {
#Override void foo() { super.foo(); }
}
In this case if we invoke the method foo in a Fred instance it will ask for the implementation of the foo method in its super class and execute that one.
Evidently, none of these others would work:
#Override void foo() { foo(); } //means this.foo() so infinite recursion
#Override void foo() { Barney.foo(); } //means a static method
There is a third configuration that we could do:
class Barney {
void foo() { System.out.println("Barney says foo"); }
class Fred extends Barney {
#Override void foo() { Barney.this.foo(); }
}
}
In this case if we invoke foo in a instance of Fred, since this instance would have a bond with its enclosing instance, this invocation would invoke the foo method in the enclosing instance of Barney.
For instance
new Barney().new Fred().foo();
So, the use of Barney.this here is used to navigate between instances in an inner/outer relation.
Using Interfaces
Now let's try to repeat the same ideas with interfaces.
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
}
interface Fred extends Barney {
#Override default void foo() { Barney.super.foo(); }
}
As far as I can tell, this is exactly the same thing as with classes, it is just that in this case since an interface can inherit from more than one interface we simply qualify the super keyword with the name of the interface we are targeting in this case.
The meaning is the same, we want to invoke the "implementation" of the foo method in the super interface explicitly named.
As with classes, the following would not work:
#Override default void foo() { super.foo(); } //can't be sure of which interface
#Override default void foo() { this.foo(); } //infinite recursion
#Override default void foo() { Barney.foo(); } //static method
#Override default void foo() { Barney.this.foo(); } //not an inner class relation
So, the logical choice here is Interface.super.method().
A question here would be whether we cab ever have a use case like Interface.this.method when using interfaces.
Not really, because interfaces represent a static context, therefore there is never a concept like that of inner classes between interfaces. So this is never possible.
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
interface Fred extends Barney {
#Override default void foo() { Barney.this.foo(); }
}
}
Basically, this is not possible because the code above does not mean that an instance of Fred would need to exist within the context of an instance of Barney. This is just a static inner interface and instances of it can exist independently of any instances of the parent interface.
So, that's why this would not be a good choice.
So, as you can see, after all this the use of super kind of makes sense, or at least I hope I have explained myself well enough to convey that idea.

This is simply an extension to default methods of the usual approach to accessing members of superclasses (JLS 15.11):
The form T.super.Identifier refers to the field named Identifier of the lexically enclosing instance corresponding to T, but with that instance viewed as an instance of the superclass of T.
Essentially, there can be ambiguity about which member is being referred to when a class has more than one ancestor (whether because of default methods or just because it has multiple superclasses in a hierarchy). The super keyword is the analog of Outer.this in an inner class; it means that you want to get "this, but the stuff I would see inside the body of that superclass instead of the member inside this subclass".

super refers to a class or interface you inherit from. It is means you want to call a method ignoring the fact it has been overridden.
If you used this you would be referring to this class (or a sub-class) and thus have infinite recursion.

Java 8 interfaces also have static methods.
If you say,
IDefaultMethod.mayOrMayNotImplementThisMethod();
Then it is a way to call static method, which also seems correct as it is similar to how we access static members of class.
For default method, if 'super' is not used then they might have used 'this', which does not make sense as 'this' belongs to class where we are making method call.
My opinion is, you are correct as it does not provide good readability but seems it is as per language design.

Related

Why I'm able to extend visuability of access modifiers in subclasses? [duplicate]

abstract class Base{
protected abstract void a();
}
class Child extends Base{
#Override
public void a(){
//why is this valid
}
}
Why is that we can't reduce the visibility but can increase it?
Also I need to implement Template pattern in which the public methods visible can only be of base class.
Example:
abstract class Base{
public void callA(){
//do some important stuff
a();
}
protected abstract void a();
}
class Child extends Base{
#Override
public void a(){
//why is this valid
}
}
Now if java allows to increase visibility then there are two methods visible publicly??
I know interface is one solution but is there some other way out???
Why decreasing visibility is not allowed is already explained in other responses (it would break the contract of the parent class).
But why it is allowed to increase the visibility of a method? First, it would not break any contract, so there is no reason to not allow it. It can be handy sometimes, when it makes sense in the child class for a method to not be protected.
Second, not allowing it could have the side effect of making impossible sometimes to extend a class and implement an interface at the same time:
interface Interface1 {
public void method();
}
public class Parent {
protected abstract void method();
}
public class Child extends Parent implements Interface1 {
#Override
public void method() {
}
//This would be impossible if the visibility of method() in class Parent could not be increased.
}
About your second question, you can do nothing about it. You have to trust that the person who implements the child class doesn't do anything that breaks your implementation. Even if java wouldn't allow to increase visibility, that would still not fix your problem, because a public method with a different name could be created that calls the abstract method:
class Child extends Base{
#Override
protected void a(){
}
public void a2() {
a(); //This would have the same problems that allowing to increase the visibility.
}
}
If the base class makes a promise regarding visibility, then the subclass cannot break that promise and still satisfy the Liskov substitution principle. You can't use a subclass in any situation where the promised method is exposed if that promise is broken.
The subclass IS-A base class. If the base class exposes a method, so must the subclass.
There's no way out in Java or C++. I'd guess the same is true in C#.
Why is that we can't reduce the visibility but can increase it?
Suppose that it would be possible to reduce the visibility. Then look at the following code:
class Super {
public void method() {
// ...
}
}
class Sub extends Super {
#Override
protected void method() {
// ...
}
}
Suppose that you would have another class, in another package, where you use these classes:
Super a = new Sub();
// Should this be allowed or not?
a.method();
To check whether a method call is allowed or not, the compiler looks at the type of the variable you call it on. The type of the variable a is Super. But the actual object that a refers to is a Sub, and there the method is protected, so you would say it should not be allowed to call the method from an unrelated class outside the package. To solve this strange situation, it's made forbidden to make overridden methods less visible.
Note that the other way around (making a method more visible) doesn't lead to the same problem.
Since Java allows Super class reference to point to sub class object.. So, restriction should not be increased from compile-time to runtime..
Lets see this through an example: -
public class B {
public void meth() {
}
}
class A extends B {
private void meth() { // Decrease visibility.
}
}
Now, you create an object of class A and assign it the reference of class B..
Lets see how: -
B obj = new A(); // Perfectly valid.
obj.meth(); // Compiler only checks the reference class..
// Since meth() method is public in class B, Compiler allows this..
// But at runtime JVM - Crashes..
Now, since compiler only checks the type of the reference variable, and check the visibility of methods in that class (class B), and it doesn't check what kind of object does the reference obj refers to.. So, it is not worried about that.. It is left to JVM at runtime to resolve the appropriate method..
But at runtime, JVM will actually try to invoke the meth method of class A as object is of class A.. But, now what happens... BooooOOMM ---> JVM Crashes.. because meth method is private in class A...
That's why visibility is not allowed to be decreased..

calling super method from unrelated method

Today I realized that calling super.foo() is possible not only inside an overriding foo method, but also inside completely unrelated methods:
class Base
{
void foo()
{
}
}
class Derived extends Base
{
void foo()
{
}
void bar()
{
super.foo();
}
}
Is there any real-world scenario, Design Pattern or whatever where this is actually useful?
This would be helpful when a child class wants to provide more meaningful names to a method than the parent class, or providing additional information about the operation in the method name.

How can I ensure that an overridden method is synchronized

I have a class of common code that is thread safe.
One of the methods in that class is abstract and needs to be overridden for different implementations.
I need to ensure or at least flag to other developers that all implementations of this method need to be thread-safe.
What is the best way to do this?
Is there a keyword or annotation to this effect?
I have already tried abstract synchronized but that combination of keywords is not allowed.
You can't do it directly. One thing you can do is have the method be concrete, but invoke an abstract method:
public synchronized final void foo() {
doFoo();
}
protected abstract void doFoo();
That way, doFoo() will always* be invoked under the synchronization established by foo().
* unless someone invokes it directly, so you should name and document it to make it clear that they shouldn't.
From Synchronized method in subclass
Synchronized is the implemenation detail of a method.
You can override a sync method with a method without declaring that as sync and vice versa.
The same holds true for the overloading also.
You can also have a look at, A synchronized method in the superclass acquires the same lock as one in the subclass.
This link to the JLS confirms that we can't mix abstract and synchronized.
Though much weaker than a keyword or standard annotation, but stronger than documentation: perhaps try a Marker interface?
... provides a means to associate metadata with a class where the
language does not have explicit support for such metadata.
This is a stretch, but might help, in that the derived class makes a declaration (edit: new example tests the declaration):
interface EatMethodIsThreadSafe {}
abstract class Animal {
public Animal() {
if (! (this instanceof EatMethodIsThreadSafe)) {
throw new IllegalArgumentException("eat method must be thread safe");
}
}
public abstract void eat();
}
public class Bear extends Animal implements EatMethodIsThreadSafe {
public synchronized void eat() {}
public static void main(String...args) { Bear b = new Bear(); }
}

trying to understand implicit superinterfaces

Sorry to bring back the dead. But I still don't clearly understand what this section of specification states.
If an interface has no direct superinterfaces, then the interface
implicitly declares a public abstract member method m with signature
s, return type r, and throws clause t corresponding to each public
instance method m with signature s, return type r, and throws clause t
declared in Object, unless a method with the same signature, same
return type, and a compatible throws clause is explicitly declared by
the interface. It is a compile-time error if the interface explicitly
declares such a method m in the case where m is declared to be final
in Object.
Given
interface Testing
{
void test();
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Now as the spec states that the above will change to
interface Testing
{
void test();
String toString();
//other non-final methods of Object
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Also. please confirm if there is an hierarchy of interfaces then all of them get these abstract methods.
What it means is that every class extends Object (at some point in its class heirarchy). However, interfaces do not extend Object. This is to avoid the problems that arise from multiple inheirtance.
Since interfaces do not extend Object that would mean we were unable to use methods like toString if the type (not class) of the object we had access to was an interface. But we know those methods must be available since all classes at some point extend from Object. Therefore, to get around this problem all of Object's not final methods are implicitly declared in all interfaces that have no superinterfaces. These contracts of these methods are always satisfied since all classes must at some point extend from Object.
TL;DR -- it's a trick to make sure we can access the methods made available by Object when we have an instance of some class stored in variable that's type is an interface (eg. Serializable)
edit: To answer your question, You're slightly off. All non-final methods of Object are added to an interface (whether they are used or not) if that interface has no parent interface AND for each method to added: that there is no matching method is explicitly declared by the interface.
As long as there is no super interface to an interface it gets the implicit declaration of the Object class methods. As long as these methods are included in the interface. Every interface that either extends or implements this interface doesn't see much difference between the methods that are explicitly declared by this interface or it got implicitly. That point forward that interface is as good as declared them explicitly.

Why can't static methods be abstract in Java?

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?
}
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.
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.
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.
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.
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
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.
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.
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.
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();
}
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.
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.
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.
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.
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.
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).
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");
}
}
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
}
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.
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.
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.
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));
}
}
Because 'abstract' means the method is meant to be overridden and one can't override 'static' methods.
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.
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.
because if you are using any static member or static variable in class it will load at class loading time.
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.
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:
Static methods do not support #overriding (runtime polymorphism), but only method hiding (compile-time polymorphism).
With #Hiding:
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:
For this reason (suppress OOPs features), Java language considers abstract + static an illegal (dangerous) combination for methods.
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
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.

Categories