Advice needed: static methods in JAVA interface - java

I have a class that is handling printing the various messages into the console, lets call this class ConsoleMessages.java. This class is public and abstract and all its methods are public and static.
I want to make an interface to this class (lets call it PrintMessages). I mean so, that ConsoleMessages.java will implement PrintMessages.
The thing is, JAVA doesn't support static methods in an interface.
What would you advise me to do?

Create the PrintMessages interface with the methods you desire.
Make ConsoleMessages a class that implements that interface. Change all methods from static to non static.
Enforce ConsoleMessages instantiation as a singleton. This can be achieved in many ways, either doing it yourself or using a Dependency Injection framework.

There is really no strong arguement against static methods in interface. Nothing bad would happen.
An interface can have static fields and static member classes though, therefore static methods can be attached through them, albeit with one extra indirection.
interface MyService
static public class Factory
static public MyService get(...)
return ...;
MyService service = MyService.Factory.get(args);

If you find yourself needing to define interfaces on a utility class then it may be time to revisit your design choices. Your ConsoleMessages class seems to have outgrown its initial use as a dumping ground for 'common utility functions'.
Short answer? Refactoring time.

Interfaces are there to specify methods for objects (which will then be implemented by some class). You have no objects here, thus you need no interface.
Static methods can only be called using the exact class name (or alternatively the name of some subclass), there is no point in using an interface to do this.
So, you have two options:
Throw your interface away and stay with the static methods.
Make all methods (or at least these which should be in the interface) non-static, and your implementing class non-abstract. To call them one then would need an object of the class (implementing this interface).

Related

How do default and static methods work in java 8 interfaces?

I have been trying to get my head around on how actually do the default and static methods work in java 8?
consider the following interface:
public interface Car {
default void drive() {
System.out.println("Default Driving");
}
static int getWheelCount(){
return wheelCount;
}
int wheelCount = 7;
}
and the following implementation:
public class Benz implements Car { }
Now if I go to my main method and write:
public static void main(String[] args){
Car car = new Benz();
car.drive();
System.out.println(Car.getWheelCount());
System.out.println(Car.wheelCount);
}
I would like to know what is really going on under the hood:
Does the default method get called upon the instance of Car in a way which is similar to how abstract classes work?
What new features/modifications did the language need in order to support default and static methods in interfaces?
I know that by default, all the fields in an interface are by default public static final, is that in any way related to my above questions.
With the introduction of default methods, do we have the need of abstract classes anymore?
P.S.
Please feel free to edit the question to make it more useful for fellow SO users.
Yes.
Java interface default methods will help us in extending interfaces without having the fear of breaking implementation classes.
What if those computer-controlled car manufacturers add new
functionality, such as flight, to their cars? These manufacturers
would need to specify new methods to enable other companies (such as
electronic guidance instrument manufacturers) to adapt their software
to flying cars. Where would these car manufacturers declare these new
flight-related methods? If they add them to their original interfaces,
then programmers who have implemented those interfaces would have to
rewrite their implementations. If they add them as static methods,
then programmers would regard them as utility methods, not as
essential, core methods.
AFAIK, static methods aren't needed to override, so being final of static methods is coherent. Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable. However, default methods must have overrideable property as I quote above.
Can you have default ctor, private fields, instance members in an interface in Java 8?
I like to use thanks to default methods,
list.sort(ordering);
instead of
Collections.sort(list, ordering);
See it seems you're a bit confused between abstract classes and interfaces.
Abstract Classes:
Within abstract classes we can abstract methods and non abstract methods. For abstract method me need not have a method definition in place and for non-abstract method we need to have a method body in place.
A class an extend only on abstract class.
Interfaces:
Interfaces in good old times(Java 7) never had a method body, with the advent of java 8 we can specify the method body with default keyword.
A class can implement multiple interfaces.
So when we need a class to conform to the features of two entities, we might make use of the interfaces. Now with default key-word, we get a default method body(of the methods of the interfaces) for our class provided by the interface itself which we might or might not choose to override and give a new method definition.
Bottom line
Whether to make use of interface or abstract class purely depends on the situational need.

Is it useful to have an abstract class without Abstract methods? [duplicate]

I am now studying a java and I'm at the part of Abstract.
I read sorta strange part to me that there is an abstract class
which does not include any abstarct method.
Why do they use this kind of class?
To prevent instantiation of that class and use it only as a base class. Child classes can use the general methods defined in the abstract class.
For example it doesn't make sense to create an instance of AbstractVehicle. But All vehicles can reuse a common registerMileage(int) method.
A common reason to do this is to have the abstract class provide exploding implementations of the abstract methods as a convenience to subclasses who don't have to implement all the abstract methods, just those they want to - the remaining ones will still explode but it won't matter if those execution paths aren't exercised.
HttpServlet is an example of this pattern in action. It has default implementations for all methods that handle the different request types, but they all throw an exception. The subclass must override these if they want to do something meaningful. It's OK to leave some handler methods not overridden as long as they are never called.
Yes, we can have abstract class without any abstract method.
Best example of abstract class without any abstract method is HttpServlet
If this class extends another abstract class and don't have implementation of inherited abstract methods.
This class contains some common logic for all its inheritors, but itself does not represent usable entity (in terms of particular application)
These type of classes are used for a implement a general logic which can be implemented by other classes. Making it abstract prevents from instantiating it. But other classes can inherit the class and its methods.
Say you have a set of related classes, but no related (shared) code, yet. If we make all of these classes extend a base class with no abstract methods, that then if we wan't all of these classes to have an identical method/feature in the future, that can be done in one shot by putting it in the base class. So code is not repeated and it reflects in all child classes by including it in just one place.
Another example for having such class is when you implement creation helpers. These classes are used to ease the client in the creation of objects, which are related in topic but decoupled depending on the need. By nature, the methods of this creator classes are all static and they can be seen as utility classes as well.Obviously, instatntation of this classes is futile and hence the abstractkeyword.
To mention a recent example I met was the Sftpclass from org.springframework.integration.dsl.sftp which is basically an easy way to require objects (e.g: adapters, gateways) from the sftp api.
I develop a abstract class to prevent instantiation of that class and use it only as a base class. because, These type of classes are used for a implement a general logic which can be implemented by other classes. Sometimes, I have a default implementation for every method in abstract class. In the manner, it doesn't force the sub-class to override all of method, but also it implement everyone that is need.It means implicitly you have to override at least one method to make scene using this abstract class.
I can't think of any good reason to use it. It could be used as "marker" but an interface would be a better choice.
Abstract class without abstract method means you can create object of that abstract class.
See my Example.
abstract class Example{
void display(){
System.out.println("Hi I am Abstract Class.");
}
}
class ExampleDemo
{
public static void main(String[] args)
{
Example ob = new Example(){};
ob.display();
}
}
If you write one abstract method inside abstract class then it will not compile.
Which means if you create abstract class without abstract method then you can create Object of that Abstract Class.

Why do we create an abstract class even though all the methods of that class are defined?

Why do we create abstract classes even though all methods of that class are already defined?
If the answer is to stop the programmer from creating an object of that class, couldn't we achieve the same thing by using a private constructor?
A class being abstract only prevents that particular class from being instantiated. Child classes may still allow instantiation.
A class with no non-private constructors prevents subclassing as well as public instantiation.
From the above you can see that these two things serve two different purposes. A class may have either—or even both properties.
The idea of the Abstract class is a common base for a number of other classes..
Think of "Animals".. You cannot create something called 'Animal'..
You have Cats and Dogs and Rabbits that 'Are' animals.
You have a abstract class called "Animal" and then you have a class called Cat that extends Animal, or Dog that extends Animal... but you do not instantiate the class "Animal" directly as its only a common base.
The design pattern of creating a class as abstract even though all methods are defined is used when the abstract class has "do nothing" or exception-throwing implementations of the methods.
We can see this in action in the HttpServlet class, which has implementations for each of the web methods (doGet(), doPost(), doPut() and doDelete()) that throw a ServletException and which a subclass must override if they want a class that does something useful for a particular web method.
Any web methods not overridden with a working implementation will explode by default.
Abstract classes show that this class in itself will not be used independently and some other concrete classes should extend it to make complete sense.
While preventing using private constructor will inhabit subclassing.
Abstract classes with no abstract methods maybe a mistake of the developer.
In Abstract class you can define the constants which are common to many class
If you have a class which only contains static methods, the you can do it abstract, as there's no need of instantiating it. I can think about utility or helper classes at least.
Specifically regarding the use of abstract vs. hiding the constructor: The abstract keyword more clearly states the architectural intent of the programmer. It's better practice.
The fact that they've provided default implementations of all the methods is a separate question.

why interface cannot be final?

JLS 2.13.1 Interface Modifiers
An interface cannot be final, because the implementation of such a class could never be completed.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
interface Type {
// Normal
class Value {
private Value() {
}
public void print() {
System.out.println("Test");
}
}
public final Value value = new Value();
}
Well in Interfaces you cannot provide any form of implementation at all: Not even static methods. It doesn't make sense to make any method final because they're yet to be implemented.
Code Examples:
If let say I have an interface named IExample and its concrete implementation Example:
interface IExample{
public final void run();
}
class Example implements IExample{
// wait! I can't override because it's final! but it's yet to be implemented?!
public void run(){
}
}
BTW: nested classes were not available when this restriction was first defined, so really the question might be why this restriction was not lifted.
A final class cannot have any sub-classes. It is considered best practice to only use interfaces for defining method(s) of sub-classes, so the two are contradictory.
You can use interfaces for other things
annotations
javadocs
constants
defining nested classes only.
but these are incidental to the purpose of an interface.
"When the final keyword appears in a class declaration, it means that the class may never be subclassed or overridden. This prevents over-specialization of a particular class. In some sense, the person who created the class considered any further changes to be tangential to its primary purpose."
Reference: Final
Interface represent behaviour, rather than implementation, therefore it makes no sense for it to be final.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
Yes, you can declare an inner class there, but point remains that a final interface would be an interface that it is impossible to implement. Any class that implemented it would be violating the final restriction. The Java designers concluded that this didn't make much sense, and since there are no convincing use-cases for final interfaces with nested classes*, there is no justification for relaxing this restriction.
* - I won't claim that one could not invent a use-case. However, I've never heard of people writing interfaces with inner classes, with the intention was that the interface should not be implemented.

Alternatives to abstract static/static override methods with generics in java

Ok so I know that you can't have an abstract static method, although I see this as a limitation personally. I also know that overriding static methods is useless because when I am dealing with say MyList<T extends ObjectWithId> and my object has an abstract class with a static method that gets overridden in it's subclasses, T doesn't exist at runtime so ObjectWithId's static method would be called instead of the subclass.
So here is what I have:
class PersistentList<T extends ObjectWithId> implements List<T>{
}
where ObjectWithId is:
abstract ObjectWithId{
public abstract long getId();
}
Now the issue is that my PersistentList is meant to be stored on hard disk, hence the name, and in reality will only store ids of objects it holds. Now when I want to implement the
#Override
public T get(int index) {
}
method of PersistentList, what I want is for my program to use the id it has stored for index and call a static method objectForId(long id) which would be implemented in each subclass of ObjectWithId. It can't be a instance method because there is no instance yet, the point is to load the instance from the hard disk using the id. So how should it be implemented? One option is to have ObjectWithId have a constructor ObjectWithId(long id) implemented in each subclass, but T doesn't exist at runtime so how would I instantiate it? I know I could pass Class<T> object in the constructor of PersistentList but I would prefer if the constructor did not have any arguments, but I don't think there is a way to get the class of T without explicitly passing it in right?
I hope this is a better explanation, sorry for the ambiguous question I started with.
While passing the Class<T> as a constructor argument, it does not really solves your problem. You then have access to the class, but to get access to the static method defined on the class you will have to use generics (unless somebody else knows a way to call a static method defined on a class from a Class object).
I would define a new generic interface which contains a generic method objectForID, something like
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
and adjust the constructor of the PersistentList to take such a ObjectRetriever instance as parameter. This ObjectRetriever can then be used to restore the objects based on their ID.
While it always seems easier to start out with static methods, I've found it to usually be beneficial to avoid static methods for just this reason, and to use instance methods by default.
The advantage to this is extensibility. Besides allowing for inheritance and avoiding the "limitations" you mentioned, it provides for extensibility - without needing to redesign things and change APIs later. For example, "this class does exactly what I need, but I wish I could change only this one portion of functionality". If there are static methods calling other static methods, there is no good way to do this. If all the methods are non-static - I can subclass that class and override only the portion of functionality required.
The other (somewhat-related) limitation to static methods is that they can't be used to implement interfaces.
In summary, I prefer to reserve static methods for "utility methods" where the function that they are performing is really clear-cut, and there isn't any feasible future reason why an alternative implementation would need to be provided.

Categories