In production code I often see classes defined as follows:
public interface SomeComponent { // Some methods }
public class SomeComponentImpl implements SomeComponent { // Some methods}
public interface SomeComponentV2 extends SomeComponent { // Some methods }
public class SomeComponentV2Impl extends SomeComponentImpl implements SomeComponent { // Some methods }
Why in this case we want to separate the interface and its implementation?
Or put it this way, why is it bad to simply have one base class, and let V2 extend/override V1 as follows:
public class SomeComponent { // Some methods }
public class SomeComponentV2 extends SomeComponent
{
// Override methods for reimplementation
// Add new methods for new features.
}
It is a good practice to separate the interface and the implementation of a class because you can easily swap out classes.
Imagine you want to test a application which depends on a web-service which bills you for every request. In addition to have a class which performs real requests to this web-service, you could build a class which implements the same interface but returns fake data to avoid generating costs for every request.
Every time you inherit from a base-class there is a chance that you inherit behaviour you simply don't want to inherit. An interface is a pure contract and gives you the freedom to let you choose a base-class independently of the described advantage.
Separating interface from implementation allows to fully use polymorphism.
In this way SomeComponentV2Impl will have 3 types - own, base class, and interface.
Here you may just use only the interface without caring about it's implementation in further classes. For example:
public void methodInOuterClass(SomeComponent smCmp){
smCmp.runInterfaceMethods();
}
[Edit: this question appeared in OP question before edites]
Why do we dont use one base class for them all?
Because SomeComponentV2Impl is distinguish from SomeComponentImpl.
But if they implement same interface, you will be able to call their implementation from the interface's refference.
Related
I have an abstract class (showing only the relevant parts) with two overloaded methods.
abstract public class Component {
...
abstract protected void createPhysics();
abstract protected void createPhysics(Comp1D[] comp1DS);
...
}
In the subclasses which extend this abstract class I only want to use either the one with arguments or the one without, but never both of them. For example
public class Comp1D extends Component{
...
protected void createPhysics(Comp1D[] comp1Ds){
...
}
}
and
public class Comp3D extends Component{
...
protected void createPhysics(){
...
}
}
Of course this won't compile this way since the other createPhysics method is not implemented in the subclass. My quick and dirty solution would be to implement both methods in subclasses, but the unused method would have empty body.
Is there a more elegant way to solve it in Java 8?
With abstract methods, there is not. And on a syntactical level, it would not be sound either. If one has a Component, one can call both methods. How should one know which one is implemented and which one is not?
One could define both method in the abstract class and let them throw, for example, an UnsupportedOperationException, thus forcing sublcasses to override (at least one of) those methods if they wish to not throw such an exception. This, however, seems like a workaround for another problem.
I would suggest re-evaluating the overall architecture of that section and find another solution to the problem. For example, maybe two separated classes and handler for those classes would yield a cleaner architecture.
The question is, why do you want to use an Abstract class here. What if you plan to use an interface, with default implementations. You can implement the interface and override only the required method
The idea of using abstract class is when you want to define common method signatures in the class and force sub-classes to provide implementation for such methods. From this point of view the way you are trying to implement abstract class doesn't make much sense.
You can also use abstract class to define a base type to support O-O features like polymorphism and inheritance and i think this is what are you trying to do .
If this is the case i suggest to declare an abstract class without abstract methods or declare an interface with default implementation for both methods and then you can override in implementation classes.
As #Turning85 pointed out, such an implementation would not make much sense.
Either you want to give your successor classes the flexibility to implement both of the methods according to their own specific needs or you want to take this complexity away from them and implement the whole logic in the abstract class, where you could have something like this:
abstract class Component() {
protected void createDefaultPhysics() {
//implement
}
abstract protected void createPhysics(Comp1D[] comp1DS);
}
and your concrete classes:
public class Comp1D extends Component{
protected void createPhysics(Comp1D[] comp1Ds){
if(comp1Ds == null) {
createDefaultPhysics();
}
}
}
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
abstract class CAR
fuelUp () { // implemented }
/ \
interface SPORTER interface TRUCK
driveFast (); moveLoad ();
Is there a way in Java I can get
a class ESTATE that has
the implementation fuelUp of CAR
and also must implement driveFast AND moveLoad?
Extending from multiple classes is not possible and making CAR an interface does not give me an implementation in CAR.
Your Java class can only extend 1 parent class, but it can implement multiple interfaces
Your class definition would be as follows:
class ESTATE extends CAR implements SPORTER, TRUCK {}
For more help, see:
https://stackoverflow.com/a/21263662/4889267
As already identified, you can extend one class and implement multiple interfaces. And in Java 8+, those interfaces can have default implementations.
But to add to this, you can also have various implementations of SPORTER, for instance. You could make use of the SporterAlpha implementation through composition.
class Foo extends Car implements Sporter {
private SporterAlpha sporterAlpha;
public int sporterMethodA(int arg1) { return sporterAlpha.sporterMethodA(arg1); }
}
Repeat as necessary to expose all the SporterAlpha methods necessary.
Thus, you can:
Inherit from no more than one superclass
Implement as many interfaces as necessary
Use default implementations on your interfaces with Java 8+
Use composition as appropriate
I have an interface with a lot of methods. (which i cannot split into different interfaces)
When i create a class that implements the interface i get a lot of methods in 1 class file.
Things get worst when the body of all these methods get larger -> the class file becomes huge and quite difficult to navigate.
Even with ide's like eclipse because the Outline window containing all classes get a vertical scrollbar because not all methods can fit in the outline.
Is there a pattern that prevents this from happening?
No there is no way to split the implementation in many classes.
But you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of methods stay the same.
I am posting this reply after an answer is accepted, hoping that future comers might find it useful.
As simas_ch said:
No there is no way to split the implementation in many classes. But
you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of
methods stay the same.
Once I worked on a rather huge application in which I had to define a Lifecycle interface, which contained many states and many functions that could create a hassle, so I came around with something like this:
You can create a class and make it abstract and implement most of the common functions.
public interface TheBigFunctional {
public void functionalA();
public void functionalB();
public void functionalC();
//....
public void functionalZ();
}
public abstract class FunctionalBase implements TheBigFunctional {
public void functionalA() {
aInternal();
}
protected abstract void aInternal();
// Rest of methods implementations.
// You may choose to skip those if you want child classes to implement them.
}
public class FunctionalTypeFoo extends FunctionalBase {
// Implementations.
}
public class FunctionalTypeBar extends FunctionalBase {
// Implementations.
}
There are many (good) ways to come around the sitation, but I am sharing what I did.
I do not quite understand why you cannot split the interface into multiple ones...
I surely would try to use inheritance, like:
First interface:
public interface FatherInterface {
String methodOne(String var);
String methodTwo(String var);
String methodThree(String var);
}
Second interface:
public interface SonInterface extends FatherInterface {
String methodFour(String var);
String methodFive(String var);
}
Third interface:
public interface SecondSonInterface extends SonInterface {
String methodSix(String var);
String methodSeven(String var);
}
And so on... Each interface inheriting from the preceding one.
As for class files becoming large, go with inheritance too.
Father class:
public class Father implements FatherInterface
Son class:
public class Son extends Father implements SonInterface
And so on...
Edit
If you cannot split the interface (as when given by third party), I would do the implementations of the methods by parts. That is, only some of them implemented in each class. Using abstract classes if needed (or leaving blank methods). Each class inheriting from the above and implementing some of the remaining methods.
Perhaps you could employ the strategy pattern on the big interface by implementing some of those methods from different classes. Then, when you wish to use any of those methods, simply call it from the class that implements your 'large' interface.
More on strategy pattern here: https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
In this case i would consider whether all methods in your class are well designed. Probably they do not have clear purpose and should be splitted per few.
You have to define clear purpose of some particular interface.
Besides, if you are using Java 8, consider ability to provide some default implementation for some methods.
Is there a pattern that prevents this from happening?
In Java:
Subtyping: If you can group sets of methods into different interfaces such that a clear hierarchical relation makes sense. This is what the accepted answer is assuming.
Interface Segregation: If you can group sets of methods into different sibling "domains" or "categories". Take a look at this example from jcabi-github. See how Github is this API's entrypoint, while exposing different sets of functionalities via successive "grouping" interfaces.
This question already has answers here:
Interface vs Abstract Class (general OO)
(36 answers)
Abstract class vs Interface in Java
(15 answers)
Closed 2 years ago.
Please tell me situation where interface is better than abstract class in Java
I think you have misunderstood the real meaning of interface and abstract class.
Interface is programming structure where you define your functions/services that you want to expose to public or other modules. Kind of a contract where you promise that you are providing some functionalities or services, but hiding the implementation so that implementation can be changed without affecting your contract.
Abstract class is a partially implemented class and it has no real meaning other than serving as a parent for multiple child classes those with real meaning. Abstract class is special parent class that provides default functionalities to multiple child classes. it is created as abstract because of unavailability of suitable concrete parent class.
In a good design, you should always create an interface. But abstract class is optional. If you can not find a concrete parent class, create an abstract class and implement the interface then provide default implementations for those interface functions (if possible) otherwise mark them as abstract functions and leave the implementation to the child classes.
A class can implement multiple interfaces, but it can only extend one abstract class.
Interfaces allow the creation of proxies that encapsulate a concrete class. This is used extensively by frameworks in order to intercept method calls to the concrete class (e.g., for starting a transaction before the method is executed or to write to the log).
Use an interface when you don't need to provide any default implementations.
Here is a nice link comparing the two: Interface vs. Abstract Class
You can only have one direct abstract superclass. Therefore, interfaces are useful if you need to expose two or more interfaces.
Java doesn't have multiple inheritance; thus, you cannot have a class that implements two abstract classes at once. For instance, if you want a MouseListener and an ActionListener in a same class, you have to do it the interface way.
An interface is better than a abstract class when you want multiple classes to implement that interface and when you don't have to inherit default behavior.
In order to provide WebServices or do JMock tests you dont need the actual implementation, you just need an interface definition. Think about it, there is no need to return the implementation to a third party when all they need to do is call your API.
When you need to implements in any class because interface can be implements in any class or interface but abstract class cant do that e.g. in Applet always Applet class extend in our Applet Application in this case we cant extend the abstract class.
Abstract Class : Define or Declare a method which is more important. Example:
Vehicle must have shape and engine. So we put this behaviour is in Abstract class.
abstract class Vehicle {
abstract void shape();
abstract void engine();
}
Interface Class : Other than that properties like move, honk, etc. So interfaces that provide additional behaviour to your concrete class.
interface Honk{
void honk();
}
interface moveable{
void move();
}
class Car extends Vehicle implements Moveable {
#Override
void shape() {
System.out.println("car's shape");
}
#Override
void Engine() {
System.out.println("car's engine");
}
#Override
void move() {
System.out.println("car's can move");
}
}
But I didn't implements Honk behaviour. If you want you can implements multiple interfaces.