Using default keyword in interface correctly - java

I have a co worker who need a method to be available to two classes.
He decided to create a new interface to be implemented by those classes.
The interface has one method
default doThis(String parameter)
It does not have any other interface methods, there is no indication that other methods would be added to this interface.
I feel this is an incorrect usage of the interface and it should be done in a different way. I.e perhaps a class which has the method allowing other classes to consume this by using the object.
Does anyone with experience on this have any opinions to share?
I can update with more clarification based on your comments.
Update:
Here is the code and the question remains:
is this a valid use of the default method or should this common logic have been done in another way like a Utilities class which does the saving to preferences ?
Interface:
public interface LogInCookie {
default void mapCookiesToPreferences(String cookie) {
if (cookie.contains(MiscConstants.HEADER_KEY_REFRESH)) {
String refreshToken = cookie.replace(MiscConstants.HEADER_KEY_REFRESH, StringUtils.EMPTY);
SharedPrefUtils.addPreference(SharedPrefConstants.REFRESH_TOKEN, refreshToken);
}
}
}
public class HDAccountActivity extends AbstractActivity implements LogInCookie {
private void mapCookies(List<String> mValue) {
LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
}
}
public class BaseSplashPage extends AppCompatActivity implements DialogClickedCallBack, LogInCookie {
//method which uses this
private void mapCookiesToPreferences(List<String> headers) {
int firstItemInHeader = 0;
for (String header : headers) {
String mValue = header.substring(firstItemInHeader,header.indexOf(MiscConstants.SEMICOLON));
LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
}
}
}

A default method in an interface, which doesn’t define other methods, can’t do much useful things with the instance of the implementing class. It can only use methods inherited from java.lang.Object, which are unlikely to carry semantics associated with the interface.
If the code doesn’t use instance methods on this at all, in other words, is entirely independent from the this instance, you should make it static, change the containing class to a non-instantiable class type, i.e.
final class SomeUtilClass {
static void doThis(String parameter) {
// ...
}
private SomeUtilClass() {} //no instances
}
and use import static packageof.SomeUtilClass.doThis; in the classes using this method.
That way, all these classes can invoke the method like doThis(…) without a qualifying type name, without needing a misleading type hierarchy.
When the method actually uses the this instance, which, as said, can only be in terms of methods inherited from java.lang.Object, the type inheritance might be justified. Since this is rather unlikely, you might still consider the type hierarchy to be misleading and rewrite the code to
final class SomeUtilClass {
static void doThis(Object firstParameter, String parameter) {
// ...
}
private SomeUtilClass() {} //no instances
}
using firstParameter instead of this, which can be invoke like doThis(this, …).

Ideally you would put that method doThis() in an abstract class that both classes extend. However if you need to achieve multiple inheritance then using an interface here is fine.
A class with a static method doThis() that you can call staticly would also work.
It all depends on how you have your project organized imo.

In java 8 , default keyword in interface was introduced for those cases where if any set of apis had long inheritance hierarchy and we wanted to introduce a method that should be available in all of the lower lying classes.
So for ex. in Java 8 stream() method was introduced in the Collection interface as a default method and it ended up being available in all of the underlying classes.
As far as your case in considered , if I go by your words then if yours is a new development then you should be using interface -> abstract class -> actual implementing class.
Only if yours was an older development setup and you already had classes implementing from an interface , that could have been an ideal scenario for using default method in your interface.

A default method in an interface
*)can have a default implementation
*)which can overridden by the implementing class
yes its a correct usage since JAVA8.
we can have default method in an interface as well as a abstract method

Related

Why does Java not allow multiple inheritance but does allow conforming to multiple interfaces with default implementations

I am not asking this -> Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?
In Java, multiple inheritance isn't allowed, but, after Java 8, Interfaces can have default methods (can implement methods itself), just like abstract classes. Within this context, it multiple inheritance should also be allowed.
interface TestInterface
{
// abstract method
public void square(int a);
// default method
default void show()
{
System.out.println("Default Method Executed");
}
}
Things are not so simple.
If a class implements multiple interfaces that defines default methods with the same signature the compiler will force you to override this method for the class.
For example with these two interfaces :
public interface Foo {
default void doThat() {
// ...
}
}
public interface Bar {
default void doThat() {
// ...
}
}
It will not compile :
public class FooBar implements Foo, Bar{
}
You should define/override the method to remove the ambiguity.
You could for example delegate to the Bar implementation such as :
public class FooBar implements Foo, Bar{
#Override
public void doThat() {
Bar.super.doThat();
}
}
or delegate to the Foo implementation such as : :
public class FooBar implements Foo, Bar {
#Override
public void doThat() {
Foo.super.doThat();
}
}
or still define another behavior :
public class FooBar implements Foo, Bar {
#Override
public void doThat() {
// ...
}
}
That constraint shows that Java doesn't allow multiple inheritancy even for interface default methods.
I think that we cannot apply the same logic for multiple inheritances because multiples issues could occur which the main are :
overriding/removing the ambiguity for a method in both inherited classes could introduce side effects and change the overall behavior of the inherited classes if they rely on this method internally. With default interfaces this risk is also around but it should be much less rare since default methods are not designed to introduce complex processings such as multiple internal invocations inside the class or to be stateful (indeed interfaces cannot host instance field).
how to inherit multiple fields ? And even if the language allowed it you would have exactly the same issue as this previously quoted : side effect in the behavior of the inherited class : a int foo field defined in a A and B class that you want to subclass doesn't have the same meaning and intention.
The language designers already thought about that, so these things are enforced by the compiler. So if you define:
interface First {
default void go() {
}
}
interface Second {
default void go() {
}
}
And you implement a class for both interfaces:
static class Impl implements First, Second {
}
you will get a compilation error; and you would need to override go to not create the ambiguity around it.
But you could be thinking that you can trick the compiler here, by doing:
interface First {
public default void go() {
}
}
static abstract class Second {
abstract void go();
}
static class Impl extends Second implements First {
}
You could think that First::go already provides an implementation for Second::go and it should be fine. This is too taken care of, thus this does not compile either.
JLS 9.4.1.3 : Similarly, when an abstract and a default method with matching signatures are inherited, we produce an error. In this case, it would be possible to give priority to one or the other - perhaps we would assume that the default method provides a reasonable implementation for the abstract method, too. But this is risky, since other than the coincidental name and signature, we have no reason to believe that the default method behaves consistently with the abstract method's contract - the default method may not have even existed when the subinterface was originally developed. It is safer in this situation to ask the user to actively assert that the default implementation is appropriate (via an overriding declaration).
The last point I would bring in, to solidify that multiple inheritance is not allowed even with new additions in java, is that static methods from interfaces are not inherited. static methods are inherited by default:
static class Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre extends Bug {
static void test() {
printIt(); // this will work just fine
}
}
But if we change that for an interface (and you can implement multiple interfaces, unlike classes):
interface Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre implements Bug {
static void test() {
printIt(); // this will not compile
}
}
Now, this is prohibited by the compiler and JLS too:
JLS 8.4.8 : A class does not inherit static methods from its superinterfaces.
Java doesn't allow multiple inheritance for fields. This would be difficult to support in the JVM as you can only have references to the start of an object where the header is, not arbitrary memory locations.
In Oracle/Openjdk, objects have a header followed by the fields of the most super class, then the next most super class, etc. It would be a significant change to allow the fields of a class to appear at different offsets relative to the header of an object for different subclasses. Most likely object references would have to become a reference to the object header and a reference to the fields to support this.
default methods in interfaces pose a problem that :
If both of the implemented interfaces define a default method with
same method signature, then the implementation class does not know
which default method to use.
The implementation class should define explicitly specify which default method to use or define it's own one.
Thus default methods in Java-8 do not facilitate multiple inheritance. The main motivation behind default methods is that if at some point we need to add a method to an existing interface, we can add a method without changing the existing implementation classes. In this way, the interface is still compatible with older versions. However, we should remember the motivation of using Default Methods and should keep the separation of interface and implementation.
The main issues with multiple inheritance are ordering (for overriding and calls to super), fields and constructors; interfaces don't have fields or constructors, so they don't cause problems.
If you look at other languages they usually fall in two broad categories:
Languages with multiple inheritance plus a few features to disambiguate special cases: virtual inheritance [C++], direct calls to all superconstructors in the most-derived class [C++], linearization of superclasses [Python], complex rules for super [Python], etc.
Languages with a differente concept, usually called interfaces, traits, mixins, modules, etc. that impose some limitations such as: no constructors [Java] or no constructors with parameters [Scala until very recently], no mutable fields [Java], specific rules for overriding (e.g. mixins take precedence over base classes [Ruby] so you can include them when you need a bunch of utility methods), etc. Java has become a language like these.
Why just by disallowing fields and constructors you solve many issues related to multiple inheritance?
You can't have duplicated fields in duplicated base classes.
The main class hierarchy is still linear.
You can't construct your base objects the wrong way.
Imagine if Object had public/protected fields and all subclasses had constructors setting those fields. When you inherit from more than one class (all of them derived from Object), which one gets to set the fields? The last class? They become siblings in the hierarchy, so they know nothing about each other. Should you have multiple copies of Object to avoid this? Would all classes interoperate correctly?
Remember that fields in Java are not virtual (overridable), they are simply data storage.
You could make a language where fields behave like methods and could be overridden (the actual storage would be always private), but that would be a much bigger change and problably wouldn't be called Java anymore.
Interfaces can't be instantiated by themselves.
You should always combine them with a concrete class. That eliminates the need for constructors and makes the programmer's intent clearer too (that is, what is meant to be a concrete class and what's an accessory interface/mixin). This also provides a well-defined place to solve all ambiguities: the concrete class.
That is mostly related to "diamonds problem" i think. Right now if you implement multiple interfaces with the same method, compiler forces you to override method the one you want to implement, because it don't know which on to use. I guess Java creators wanted to remove this problem back when interfaces couldn't use default methods. Now they came up with idea, that is good to be able to have methods with implementation in interfaces, as you can still use those as functional interfaces in streams / lambda expressions and utilize their default methods in processing. You cannot do that with classes but diamond problem still exist there. That is my guess :)
class A{
void m1(){
System.out.println("m1-A");
}
}
class B{
void m1(){
System.out.println("m1-B");
}
}
class C extends A, B{ // this will give an error
// inheritance means making all variables and/or methods available to the child class, here child class will get confused as which m1() method to inherit, hence an error
}
JAVA DOES SUPPORT MULTIPLE INHERITANCE.
If you make a OVERALL COMPARISON OF THE PROGRAMMING LANGUAGE,JAVA,THEN YOU COME TO KNOW THAT I AM TRUE.
Java's topclass or the root class in the Ancestor Hierarchy is the Object class.
This class is a Superclass of all other classes. Hence, each class in Java that we declare or is predefined in the API itself inherits this Object class.
Moreover, Java provides us to inherit one more class of our choice.
Hence, we can say that we are performing INTERLOCKED BUT MULTIPLE INHERITANCE.
2ND Way
Java supports Multiple Inheritance of Interfaces. So you can use as many interface implementations you want. But note, implementing an interface does not define IS A relationship as in case of Inheritance of Classes is possible.

why Java 8 interface static methods cannot override Object class methods [duplicate]

I'm confused why the following is not allowed:
public interface MyInterface {
MyInterface getInstance(String name);
}
public class MyImplementation implements MyInterface {
public MyImplementation(String name) {
}
#Override
public static MyInterface getInstance(String name) { // static is not allowed here
return new MyImplementation(name)
}
}
I understand why a method in the interface cannot be static, but why can't the overriding method be?
I want all classes to implement the getInstance(String name) method, but I'm currently limited to only being able to call the method if the object has already been instantiated which kind of defeats the purpose...
*update:* Thanks for the answers, I understand it better now. Basically I shouldn't be trying to make a utility class (or a factory class for that matter) implement an interface (or at least, not in this way)...
Invoking static methods in Java requires you to specify the exact type. It is not possible to invoke static methods polymorphically, eliminating the need for #Override.
Please note that this approach is not universal across all languages: for example, you can override class methods in Objective-C, and Apple's cocoa frameworks make good use of this mechanism to customize their "factory" classes. However, in Java, C++, and C# class methods do not support polymorphic behavior.
Theoretically, Java designers could have let you provide interface method implementations through static methods in case an implementation does not need to access the state from the instance. But the same behavior is simple to achieve with a trivial wrapper:
public class MyImplementation implements MyInterface {
public MyImplementation(String name) {
}
#Override
public MyInterface getInstance() { // static is not allowed here
return getInstanceImpl();
}
public static getInstanceImpl() {
return new MyImplementation(name)
}
}
Java compiler could have done the same thing on your behalf, but seeing a static method implement an instance method is both unusual and confusing, so my guess is that Java designers decided against providing this "piece of magic".
Static methods cannot be subject to polymorphic behavior. That would not make much sense. Image this use case, assuming what you want would be possible:
public void foo(MyInterface i) {
i.getInstance("abc");
}
now I want to call this method with an implementation of MyInterface (class A), but since I cannot pass the class itself, I need to pass an object:
A a = new A();
foo(a);
now inside foo the static override of getInstance is called on the instance of class A. So now I am stuck with creating an object just to call a static method.
My point is that you would still be constrained to create an object in most use cases of polymorphism since in your original interface the method was an instance method.
because implementing an interface makes the implementor the type of the interface. That means instances need to have the methods defined by the type, not the class of the instances.
To put it another way,
public void mymethod
and
public static void mymethod
are NOT the same method declaration. They are completely distinct. If mymethod is defined on an interface, having the second definition simply does not satisfy implementing the interface.
The answer comes down to what it means to implement an interface. When a class implements an interface, that is a promise that every instance of the class will respond to every method in the interface. When you implement the method as static, you make it possible to call the method without an instance of the class - but that doesn't fulfill the inheritance implementation's promise that the method will be callable on every instance of the class.

Protect "default" methods from overriding

I'm looking for a solution, that allows to protect the default methods from inheritance. The easiest solution could be - extend from class and etc... but in my case it's not possible.
Can someone suggest how to solve this problem? Could there be any workarounds?
Atm I have following code, which needs to be reworked (if/any possible):
public interface MyInterface1 {
default boolean isA(Object obj) {
return (boolean) obj.equals("A") ? true : false;
}
default boolean isB(Object obj) {
return (boolean) obj.equals("B") ? true : false;
}
}
public class MyClass extends MyLogic implements MyInterface, MyInterface1 {
// this class allows to inherit methods from both interfaces,
// but from my perspective i'd like to use the methods from MyInterface1 as it is,
// with a 'protection' from inheritance. is that possible?
}
You seem to want a way to write your interface so that implementing classes cannot provide their own implementations of its default methods. There is no way to do this, and indeed it runs counter to the purpose of interfaces in general and default members in particular.
The point of default methods is to provide a way to add methods to existing interfaces without instantly breaking all their existing implementations. Generally speaking, this is a binary compatibility issue, not a functionality issue. There's no particular reason to suppose in general that default implementations can provide the intended functionality, but without them, even old code that doesn't rely on the new methods at all is incompatible with interface revisions that add methods.
I think you have a factoring issue. Rather than trying to force classes to provide a specific implementation of a specific method -- which cannot even refer to that class's members, except possibly others defined by the same interface -- you should provide the common methods in a class of their own. After all, since you want all classes involved to provide identical implementations, it doesn't matter which class's implementations you actually use. Moreover, there is therefore no particular usefulness in marking any given class as providing implementations of the well-known methods.
Example:
public class MyImplementation1 {
public static boolean isA(Object obj) {
return obj.equals("A");
}
public static isB(Object obj) {
return obj.equals("B");
}
}
// Wherever needed, use as MyImplementation1.isA(o), etc.
You can do this even if you want these pre-baked implementations to operate in terms of the other methods of your interface. In that case, just add an argument to the fixed methods that provides the object to operate on. Perhaps that's what the obj arguments in your example were supposed to be; in that case, this may be closer to what you're after:
public interface MyInterface3 {
public String someInterfaceMethod();
}
public class MyImplementation2 {
public static boolean isA(MyInterface3 subject) {
return subject.someInterfaceMethod().equals("A");
}
public static boolean isB(MyInterface3 subject) {
return subject.someInterfaceMethod().equals("B");
}
}
You can't. At least if you restrict yourself to a pure-java-compiler solution.
And the reason is because it was not designed to do that: the purpose is to add new methods to existing interface (like java.util.Collection) without breaking the implementations. That way, we have sort(), stream(), forEach() on Collection.
If you were to allow such thing (forbidding implementation), then it would means a change in the interface would result in a compilation error for implementation (because they would override the method, method that would been rendered final). That was not the purpose.
There are several other options to achieve that, depending on your need:
Abstract class with final method being the previously default method.
Testing the default behavior using unit testing.
Testing the possible implementation and check they don't override it.
The last case can probably be done easily with Reflections: you would have to list all implementations, and check for each interface's default method that there is no overriding using Reflections.
I take it you mean you want to write a class that uses the default methods of an interface, but does not inherit them.
In your example code, you attempted to use the default methods by implementing the interface. When you implement an interface, by design you also inherit all its methods. This is the Liskov Substitution Principle. By implementing the interface you are telling your users that all instances of your class are substitutable for instances of the interface. But if the interface default methods weren't inherited, this wouldn't be true, so you would be lying to users of your class.
To have your class use the interface's default methods without inheriting them, don't implement the interface! Instead, use a helper class that does:
public interface MyInterface1 {
default boolean isA(Object obj) {
return obj.equals("A"); // or "A".equals(obj) to avoid NullPointerException
}
default boolean isB(Object obj) {
return obj.equals("B");
}
}
public class MyClass extends MyLogic implements MyInterface {
private static class Helper implements MyInterface1 {
void doSomeWork() {
// do something that calls isA() and isB()...
}
}
public void someMethodOfMyClass() {
// ...
Helper.doSomeWork();
// ...
}
}
No, This is not possible due to the way java implements the interface (pun intended). For more information as to the reason for this, see the answers to this question Why is "final" not allowed in Java 8 interface methods?
However here are some other ways to guide a developer not to override a default method:
A source code comment
//Do not inherit please
A javadoc comment

How to use reflection mechanisms to invoke a public method that resides in a base class with default visibility?

This question concerns the reflection mechanisms of the java programming language.
I have an interface:
package A;
public interface MyInterface {
public boolean doSomething(Object... parameters);
}
I have several implementation classes for this interface. Here some examples:
package B;
import A.*;
abstract class BaseImplementation implements MyInterface {
private Object field;
protected BaseImplementation() {
super();
}
public void setField(Object aField) {
field = aField;
}
public Object getField() {
return field;
}
}
package B;
import A.*;
public class ConcreteImplementation extends BaseImplementation {
public ConcreteImplementation() {
super();
}
...
// The concrete implementation provides an implementation for all
// inherited abstract methods. Apart from this no other methods
// are overridden.
// This concrete class provides accessor methods for all of its own
// private fields.
...
}
(edited) As a sidenote (this may not be relevant to the issue concerning the reflection mechanism):
I'm implementing a complex ruleset. One drawback of this ruleset is that there are lots of interdependencies between objects. Thus there is a need to define the general behaviour with interfaces. When implementing one part of the ruleset you have to consider the behaviour of another, not yet implemented, part.
Different implementations of an interface require different resources/objects to work properly. To reduce duplicate code I use the abstract parent classes. These abstract classes are not used outside of their packages.
When instantiating and initializing an instance of a concrete implementation class I resort to reflection mechanisms. For this purpose I have a utility class (which resides in a separate package) where I have to specify the desired classname, which field gets which value (i.e. the appropriate setter methods will be looked up then) and the order in which the setter methods are called.
I have two different development environments and on each a different version of java is installed (1.5.x and 1.6.x). This is mainly used for cross checking the behaviour of the implementation.
Instantiating an instance of a concrete implementation class works in both environments. But the
initialization fails with the older java version. Somehow the public setter method of the base class (the base class has a default visibility) cannot be accessed. The newer java version has no issues with accessing the setter method.
One workaround I found is to change the visibility of the base class (default -> public). The question is, is there a way to keep the visibility (default) and still call the setter method with reflection mechanisms?
Depending on what security restrictions you have in place you can use
AccessibleObject.setAccessible(boolean);
(AccessibleObject is an interface implemented by Field, Method, Constructor). Before your reflections call just invoke method.setAccessible(true); on the reflections object and unless the SecurityManager throws an Exception you should be fine.

Why can't I define a static method in a Java interface?

EDIT: As of Java 8, static methods are now allowed in interfaces.
Here's the example:
public interface IXMLizable<T>
{
static T newInstanceFromXML(Element e);
Element toXMLElement();
}
Of course this won't work. But why not?
One of the possible issues would be, what happens when you call:
IXMLizable.newInstanceFromXML(e);
In this case, I think it should just call an empty method (i.e. {}). All subclasses would be forced to implement the static method, so they'd all be fine when calling the static method. So why isn't this possible?
EDIT: I guess I'm looking for answer that's deeper than "because that's the way Java is".
Is there a particular technological reason why static methods can't be overwritten? That is, why did the designers of Java decide to make instance methods overrideable but not static methods?
EDIT: The problem with my design is I'm trying to use interfaces to enforce a coding convention.
That is, the goal of the interface is twofold:
I want the IXMLizable interface to allow me to convert classes that implement it to XML elements (using polymorphism, works fine).
If someone wants to make a new instance of a class that implements the IXMLizable interface, they will always know that there will be a newInstanceFromXML(Element e) static constructor.
Is there any other way to ensure this, other than just putting a comment in the interface?
Java 8 permits static interface methods
With Java 8, interfaces can have static methods. They can also have concrete instance methods, but not instance fields.
There are really two questions here:
Why, in the bad old days, couldn't interfaces contain static methods?
Why can't static methods be overridden?
Static methods in interfaces
There was no strong technical reason why interfaces couldn't have had static methods in previous versions. This is summed up nicely by the poster of a duplicate question. Static interface methods were initially considered as a small language change, and then there was an official proposal to add them in Java 7, but it was later dropped due to unforeseen complications.
Finally, Java 8 introduced static interface methods, as well as override-able instance methods with a default implementation. They still can't have instance fields though. These features are part of the lambda expression support, and you can read more about them in Part H of JSR 335.
Overriding static methods
The answer to the second question is a little more complicated.
Static methods are resolvable at compile time. Dynamic dispatch makes sense for instance methods, where the compiler can't determine the concrete type of the object, and, thus, can't resolve the method to invoke. But invoking a static method requires a class, and since that class is known statically—at compile time—dynamic dispatch is unnecessary.
A little background on how instance methods work is necessary to understand what's going on here. I'm sure the actual implementation is quite different, but let me explain my notion of method dispatch, which models observed behavior accurately.
Pretend that each class has a hash table that maps method signatures (name and parameter types) to an actual chunk of code to implement the method. When the virtual machine attempts to invoke a method on an instance, it queries the object for its class and looks up the requested signature in the class's table. If a method body is found, it is invoked. Otherwise, the parent class of the class is obtained, and the lookup is repeated there. This proceeds until the method is found, or there are no more parent classes—which results in a NoSuchMethodError.
If a superclass and a subclass both have an entry in their tables for the same method signature, the sub class's version is encountered first, and the superclass's version is never used—this is an "override".
Now, suppose we skip the object instance and just start with a subclass. The resolution could proceed as above, giving you a sort of "overridable" static method. The resolution can all happen at compile-time, however, since the compiler is starting from a known class, rather than waiting until runtime to query an object of an unspecified type for its class. There is no point in "overriding" a static method since one can always specify the class that contains the desired version.
Constructor "interfaces"
Here's a little more material to address the recent edit to the question.
It sounds like you want to effectively mandate a constructor-like method for each implementation of IXMLizable. Forget about trying to enforce this with an interface for a minute, and pretend that you have some classes that meet this requirement. How would you use it?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
Since you have to explicitly name the concrete type Foo when "constructing" the new object, the compiler can verify that it does indeed have the necessary factory method. And if it doesn't, so what? If I can implement an IXMLizable that lacks the "constructor", and I create an instance and pass it to your code, it is an IXMLizable with all the necessary interface.
Construction is part of the implementation, not the interface. Any code that works successfully with the interface doesn't care about the constructor. Any code that cares about the constructor needs to know the concrete type anyway, and the interface can be ignored.
This was already asked and answered, here
To duplicate my answer:
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
The reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.
While you can say that this amounts to "because Java does it that way", in reality the decision is a logical consequence of other design decisions, also made for very good reason.
With the advent of Java 8 it is possible now to write default and static methods in interface.
docs.oracle/staticMethod
For example:
public interface Arithmetic {
public int add(int a, int b);
public static int multiply(int a, int b) {
return a * b;
}
}
public class ArithmaticImplementation implements Arithmetic {
#Override
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int result = Arithmetic.multiply(2, 3);
System.out.println(result);
}
}
Result : 6
TIP : Calling an static interface method doesn't require to be implemented by any class. Surely, this happens because the same rules for static methods in superclasses applies for static methods on interfaces.
Normally this is done using a Factory pattern
public interface IXMLizableFactory<T extends IXMLizable> {
public T newInstanceFromXML(Element e);
}
public interface IXMLizable {
public Element toXMLElement();
}
Because static methods cannot be overridden in subclasses, and hence they cannot be abstract. And all methods in an interface are, de facto, abstract.
Why can't I define a static method in a Java interface?
Actually you can in Java 8.
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 an interface can have default methods and static methods. 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.
Example of default method:
list.sort(ordering);
instead of
Collections.sort(list, ordering);
Example of static method (from 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));
}
}
Interfaces are concerned with polymorphism which is inherently tied to object instances, not classes. Therefore static doesn't make sense in the context of an interface.
First, all language decisions are decisions made by the language creators. There is nothing in the world of software engineering or language defining or compiler / interpreter writing which says that a static method cannot be part of an interface. I've created a couple of languages and written compilers for them -- it's all just sitting down and defining meaningful semantics. I'd argue that the semantics of a static method in an interface are remarkably clear -- even if the compiler has to defer resolution of the method to run-time.
Secondly, that we use static methods at all means there is a valid reason for having an interface pattern which includes static methods -- I can't speak for any of you, but I use static methods on a regular basis.
The most likely correct answer is that there was no perceived need, at the time the language was defined, for static methods in interfaces. Java has grown a lot over the years and this is an item that has apparently gained some interest. That it was looked at for Java 7 indicates that its risen to a level of interest that might result in a language change. I, for one, will be happy when I no longer have to instantiate an object just so I can call my non-static getter method to access a static variable in a subclass instance ...
"Is there a particular reason that static methods cannot be overridden".
Let me re-word that question for your by filling in the definitions.
"Is there a particular reason that methods resolved at compile time cannot be resolved at runtime."
Or, to put in more completely, If I want to call a method without an instance, but knowing the class, how can I have it resolved based upon the instance that I don't have.
Static methods aren't virtual like instance methods so I suppose the Java designers decided they didn't want them in interfaces.
But you can put classes containing static methods inside interfaces. You could try that!
public interface Test {
static class Inner {
public static Object get() {
return 0;
}
}
}
Commenting EDIT: As of Java 8, static methods are now allowed in interfaces.
It is right, static methods since Java 8 are allowed in interfaces, but your example still won't work. You cannot just define a static method: you have to implement it or you will obtain a compilation error.
Several answers have discussed the problems with the concept of overridable static methods. However sometimes you come across a pattern where it seems like that's just what you want to use.
For example, I work with an object-relational layer that has value objects, but also has commands for manipulating the value objects. For various reasons, each value object class has to define some static methods that let the framework find the command instance. For example, to create a Person you'd do:
cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();
and to load a Person by ID you'd do
cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();
This is fairly convenient, however it has its problems; notably the existence of the static methods can not be enforced in the interface. An overridable static method in the interface would be exactly what we'd need, if only it could work somehow.
EJBs solve this problem by having a Home interface; each object knows how to find its Home and the Home contains the "static" methods. This way the "static" methods can be overridden as needed, and you don't clutter up the normal (it's called "Remote") interface with methods that don't apply to an instance of your bean. Just make the normal interface specify a "getHome()" method. Return an instance of the Home object (which could be a singleton, I suppose) and the caller can perform operations that affect all Person objects.
Why can't I define a static method in a Java interface?
All methods in an interface are explicitly abstract and hence you cannot define them as static because static methods cannot be abstract.
Well, without generics, static interfaces are useless because all static method calls are resolved at compile time. So, there's no real use for them.
With generics, they have use -- with or without a default implementation. Obviously there would need to be overriding and so on. However, my guess is that such usage wasn't very OO (as the other answers point out obtusely) and hence wasn't considered worth the effort they'd require to implement usefully.
An interface can never be dereferenced statically, e.g. ISomething.member. An interface is always dereferenced via a variable that refers to an instance of a subclass of the interface. Thus, an interface reference can never know which subclass it refers to without an instance of its subclass.
Thus the closest approximation to a static method in an interface would be a non-static method that ignores "this", i.e. does not access any non-static members of the instance. At the low-level abstraction, every non-static method (after lookup in any vtable) is really just a function with class scope that takes "this" as an implicit formal parameter. See Scala's singleton object and interoperability with Java as evidence of that concept.
And thus every static method is a function with class scope that does not take a "this" parameter. Thus normally a static method can be called statically, but as previously stated, an interface has no implementation (is abstract).
Thus to get closest approximation to a static method in an interface, is to use a non-static method, then don't access any of the non-static instance members. There would be no possible performance benefit any other way, because there is no way to statically link (at compile-time) a ISomething.member(). The only benefit I see of a static method in an interface is that it would not input (i.e. ignore) an implicit "this" and thus disallow access to any of the non-static instance members. This would declare implicitly that the function that doesn't access "this", is immutate and not even readonly with respect to its containing class. But a declaration of "static" in an interface ISomething would also confuse people who tried to access it with ISomething.member() which would cause a compiler error. I suppose if the compiler error was sufficiently explanatory, it would be better than trying to educate people about using a non-static method to accomplish what they want (apparently mostly factory methods), as we are doing here (and has been repeated for 3 Q&A times on this site), so it is obviously an issue that is not intuitive for many people. I had to think about it for a while to get the correct understanding.
The way to get a mutable static field in an interface is use non-static getter and setter methods in an interface, to access that static field that in the subclass. Sidenote, apparently immutable statics can be declared in a Java interface with static final.
Interfaces just provide a list of things a class will provide, not an actual implementation of those things, which is what your static item is.
If you want statics, use an abstract class and inherit it, otherwise, remove the static.
Hope that helps!
You can't define static methods in an interface because static methods belongs to a class not to an instance of class, and interfaces are not Classes. Read more here.
However, If you want you can do this:
public class A {
public static void methodX() {
}
}
public class B extends A {
public static void methodX() {
}
}
In this case what you have is two classes with 2 distinct static methods called methodX().
Suppose you could do it; consider this example:
interface Iface {
public static void thisIsTheMethod();
}
class A implements Iface {
public static void thisIsTheMethod(){
system.out.print("I'm class A");
}
}
class B extends Class A {
public static void thisIsTheMethod(){
System.out.print("I'm class B");
}
}
SomeClass {
void doStuff(Iface face) {
IFace.thisIsTheMethod();
// now what would/could/should happen here.
}
}
Something that could be implemented is static interface (instead of static method in an interface). All classes implementing a given static interface should implement the corresponding static methods. You could get static interface SI from any Class clazz using
SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null
then you can call si.method(params).
This would be useful (for factory design pattern for example) because you can get (or check the implementation of) SI static methods implementation from a compile time unknown class !
A dynamic dispatch is necessary and you can override the static methods (if not final) of a class by extending it (when called through the static interface).
Obviously, these methods can only access static variables of their class.
While I realize that Java 8 resolves this issue, I thought I'd chime in with a scenario I am currently working on (locked into using Java 7) where being able to specify static methods in an interface would be helpful.
I have several enum definitions where I've defined "id" and "displayName" fields along with helper methods evaluating the values for various reasons. Implementing an interface allows me to ensure that the getter methods are in place but not the static helper methods. Being an enum, there really isn't a clean way to offload the helper methods into an inherited abstract class or something of the like so the methods have to be defined in the enum itself. Also because it is an enum, you wouldn't ever be able to actually pass it as an instanced object and treat it as the interface type, but being able to require the existence of the static helper methods through an interface is what I like about it being supported in Java 8.
Here's code illustrating my point.
Interface definition:
public interface IGenericEnum <T extends Enum<T>> {
String getId();
String getDisplayName();
//If I was using Java 8 static helper methods would go here
}
Example of one enum definition:
public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
STANDARD ("Standard", "Standard Mode"),
DEBUG ("Debug", "Debug Mode");
String id;
String displayName;
//Getter methods
public String getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
//Constructor
private ExecutionModeType(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}
//Helper methods - not enforced by Interface
public static boolean isValidId(String id) {
return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
}
public static String printIdOptions(String delimiter){
return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
}
public static String[] getIdArray(){
return GenericEnumUtility.getIdArray(ExecutionModeType.class);
}
public static ExecutionModeType getById(String id) throws NoSuchObjectException {
return GenericEnumUtility.getById(ExecutionModeType.class, id);
}
}
Generic enum utility definition:
public class GenericEnumUtility {
public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(enumOption.getId().equals(id)) {
return true;
}
}
return false;
}
public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
String ret = "";
delimiter = delimiter == null ? " " : delimiter;
int i = 0;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(i == 0) {
ret = enumOption.getId();
} else {
ret += delimiter + enumOption.getId();
}
i++;
}
return ret;
}
public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
List<String> idValues = new ArrayList<String>();
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
idValues.add(enumOption.getId());
}
return idValues.toArray(new String[idValues.size()]);
}
#SuppressWarnings("unchecked")
public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
id = id == null ? "" : id;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(id.equals(enumOption.getId())) {
return (T)enumOption;
}
}
throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
}
}
Let's suppose static methods were allowed in interfaces:
* They would force all implementing classes to declare that method.
* Interfaces would usually be used through objects, so the only effective methods on those would be the non-static ones.
* Any class which knows a particular interface could invoke its static methods. Hence a implementing class' static method would be called underneath, but the invoker class does not know which. How to know it? It has no instantiation to guess that!
Interfaces were thought to be used when working with objects. This way, an object is instantiated from a particular class, so this last matter is solved. The invoking class need not know which particular class is because the instantiation may be done by a third class. So the invoking class knows only the interface.
If we want this to be extended to static methods, we should have the possibility to especify an implementing class before, then pass a reference to the invoking class. This could use the class through the static methods in the interface. But what is the differente between this reference and an object? We just need an object representing what it was the class. Now, the object represents the old class, and could implement a new interface including the old static methods - those are now non-static.
Metaclasses serve for this purpose. You may try the class Class of Java. But the problem is that Java is not flexible enough for this. You can not declare a method in the class object of an interface.
This is a meta issue - when you need to do ass
..blah blah
anyway you have an easy workaround - making the method non-static with the same logic. But then you would have to first create an object to call the method.
To solve this :
error: missing method body, or declare abstract
static void main(String[] args);
interface I
{
int x=20;
void getValue();
static void main(String[] args){};//Put curly braces
}
class InterDemo implements I
{
public void getValue()
{
System.out.println(x);
}
public static void main(String[] args)
{
InterDemo i=new InterDemo();
i.getValue();
}
}
output :
20
Now we can use static method in interface
I think java does not have static interface methods because you do not need them. You may think you do, but...
How would you use them? If you want to call them like
MyImplClass.myMethod()
then you do not need to declare it in the interface. If you want to call them like
myInstance.myMethod()
then it should not be static.
If you are actually going to use first way, but just want to enforce each implementation to have such static method, then it is really a coding convention, not a contract between instance that implements an interface and calling code.
Interfaces allow you to define contract between instance of class that implement the interface and calling code. And java helps you to be sure that this contract is not violated, so you can rely on it and don't worry what class implements this contract, just "someone who signed a contract" is enough. In case of static interfaces your code
MyImplClass.myMethod()
does not rely on the fact that each interface implementation has this method, so you do not need java to help you to be sure with it.
What is the need of static method in interface, static methods are used basically when you don't have to create an instance of object whole idea of interface is to bring in OOP concepts with introduction of static method you're diverting from concept.

Categories

Resources