Separating the interface from an implementation in Java - java

How can you separate the interface from an implementation in Java?
In C/C++, this can be done by creating 2 files a .c and .h file with the same file name.
How can you do this in Java?

The closest analogy to .h and .c separation is interfaces.
MyInterface.java
interface MyInterface {
void doSomething();
}
MyImplementation.java
class MyImplementation implements MyInterface {
public void doSomething() {
System.out.println("Hello world");
}
}
You then use the interface type everywhere except for the actual constructor
MyInterface instance = new MyImplementation();
Of course, there are several differences.
A single class may implement multiple interfaces, and multiple classes may a single interface
Member values are not included in an interface, only methods.
Only public methods appears in a Java interface.
No implementation is ever allowed in an interface (as opposed to C++ templates, which depend on .h implementation).
But this is how "programming to interfaces" is accomplished.
There is no consistent convention for naming interfaces vs concrete classes in Java. C# (nearly identical in its treatment of interfaces) has a convention which I have come to use where the interface begins with I, e.g. IList. The Java standard libraries tend to use the "pure" name for the interface, and then modify it for the concrete implementation, such as List (interface) and ArrayList (implementation).

By creating an interface, and implementing it also (generally) in two files -
Say.java the interface -
public interface Say {
public void say(String msg);
}
and Hello.java, the concrete implementation (and in this case) also a main() method -
public class Hello implements Say {
#Override
public void say(String msg) {
System.out.printf("%s, World!%n", msg);
}
public static void main(String[] args) {
Say s = new Hello();
s.say("Hello");
}
}
Note: In Java you can have multiple classes with main() methods. It is also a good practice to use the #Override annotation.

You don't. You could do it via Java interfaces, but doing that for every class would be bad design. Interfaces should only be used when you expect multiple classes to implement them, or when used as a callback function description. Really the point of separating the code from the .h file in C++ is
1)To prevent bloating the binary as compilers would make multiple versions of each function for each file its included in
2)To make it easier to read for those who just want the implementation.
In java, 1 isn't an issue. And Java prefers to solve 2 via automated documentation tools (JavaDoc).
TLDR- you don't.

In Java, interfaces and classes (ie "implementation") are NOT distinguished at file level or by their names. They are both declarations. Specifically, a class declares which interface(s) it implements. For example:
public class MyClass implements Interface1, Interface2, .... {
// implementations
}
Java does not have the same "linking" concept as in C/C++. You can call your class or interface in any legal form. The "link" between an interface and its implementation classes at runtime are done through the class loader.

To have an interface and implementation separated, suggest below steps..
( 1).Identify methods which be part of definition of your class. This becomes your template for new classes with similar functionality.
(2 ). Create a new interface which contains methods which were identified to be part of interface definition (may be many interfaces)
( 3.) Modify your class to implement the interface(s) you have created

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.

Are there any differences between a normal interface class and an abstract class that only has abstract methods?

I was just curious if they are treated any differently.
For example if we have:
The interface:
public interface Test {
public void method();
}
And the abstract class:
public abstract class Test {
public abstract void method();
}
Will the JVM treat these classes any differently? Which of the two takes up more disk space during storage, which one will use up the most runtime memory which one does more operations(performs better).
This question isn't about when to use interfaces or abstract classes.
Yes, they are different.
With an interface, clients could implement it aswell as extend a class:
class ClientType implements YourInterface, SomeOtherInterface { //can still extend other types
}
With a class, clients will be able to extend it, but not extend any other type:
class ClientType extends YourClass { //can no longer extend other types
}
Another difference arises when the interface or abstract class have only a single abstract method declaration, and it has to do with anonymous functions (lambdas).
As #AlexanderPetrov said, an interface with one method can be used as a functional interface, allowing us to create functions "on-the-fly" where ever a functional interface type is specified:
//the interface
interface Runnable {
void run()
}
//where it's specified
void execute(Runnable runnable) {
runnable.run();
}
//specifying argument using lambda
execute(() -> /* code here */);
This cannot be done with an abstract class.
So you cannot use them interchangably. The difference comes in the limitations of how a client can use it, which is enforced by the semantics of the JVM.
As for differences in resource usage, it's not something to worry about unless it's causing your software problems. The idea of using a memory-managed language is to not worry about such things unless you are having problems. Don't preoptimize, I'm sure the difference is negligable. And even if there is a difference, it should only matter if it may cause a problem for your software.
If your software is having resource problems, profile your application. If it does cause memory issues, you will be able to see it, as well as how much resources each one consumes. Until then, you shouldn't worry about it. You should prefer the feature that makes your code easier to manage, as opposed to which consumes the least amount of resources.
JVM internals and memory representation
It will be almost the same for the JVM. My statement is based on Chapter 4 - Class file Format. As seen from the attached documentation the JVM is making difference between a class and interface, by the access_flags. If you have a Simple interface with just one method and a simple abstract class with just one method. Most of the fields in this format will be the same (empty) and the main difference will be the access_flags.
Default constructor generation abstract class
As #Holger pointed out, another small difference between the Interface and Abstract class is that ordinary classes require a constructor. The Java compiler will generate a default constructor for the Abstract class which will be invoked for each of its subclasses. In that sense the abstract class definition will be slightly bigger compared to the interface.
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Besides the multiple inheritance of interfaces, another difference is that in Java8 abstract class with only one method is not a Functional interface.
#FunctionalInterface
public interface SimpleFuncInterface {
public void doWork();
}
execute(SimpleFuncInterface function) {
function.doWork();
}
execute(()->System.out.printline("Did work"));
Same can not be achieved with abstract class.
Interfaces - lack of "Openness to extension".
Up to Java 8 Interfaces have been criticized for their lack of extensibility. If you change the interface contract you need to refactor all clients of an interface.
One example that comes to mind is Java MapReduce API for Hadoop, which
was changed in 0.20.0 release to favour abstract classes over
interfaces, since they are easier to evolve. Which means, a new method
can be added to abstract class (with default implementation), with out
breaking old implementations of the class.
With the introduction of Java 8 Interface Default method
this lack of extensibility has been addressed.
public interface MyInterface {
int method1();
// default method, providing default implementation
default String displayGreeting(){
return "Hello from MyInterface";
}
}
With Java 8 new methods can be added both to interfaces and abstract classes without breaking the contract will the client classes.
http://netjs.blogspot.bg/2015/05/interface-default-methods-in-java-8.html
They are different in implementation
you can only extend only one abstract class
On the other hand you can implement multiple interfaces at the same time
You need to implement all method present in an interface
for abstract it may provide some default implementation so you are independent whether you want to implement it again or just used the default implementation
If you talking about performance, then sometime ago there was an opinion that interfaces are slower than abstract classes. But now JIT makes no difference between them.
Please, see this answer for more details.

What is the purpose of the default keyword in Java?

An interface in Java is similar to a class, but the body of an
interface can include only abstract methods and final fields
(constants).
Recently, I saw a question, which looks like this
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
According to the interface definition, only abstract methods are allowed. Why does it allow me to compile the above code? What is the default keyword?
On the other hand, when I was trying to write below code, then it says modifier default not allowed here
default class MyClass{
}
instead of
class MyClass {
}
Can anyone tell me the purpose of the default keyword? Is it only allowed inside an interface? How does it differ from default (no access modifier)?
It's a new feature in Java 8 which allows an interface to provide an implementation. Described in Java 8 JLS-13.5.6. Interface Method Declarations which reads (in part)
Adding a default method, or changing a method from abstract to default, does not break compatibility with pre-existing binaries, but may cause an IncompatibleClassChangeError if a pre-existing binary attempts to invoke the method. This error occurs if the qualifying type, T, is a subtype of two interfaces, I and J, where both I and J declare a default method with the same signature and result, and neither I nor J is a subinterface of the other.
What's New in JDK 8 says (in part)
Default methods enable new functionality to be added to the interfaces of libraries and ensure binary compatibility with code written for older versions of those interfaces.
Default methods were added to Java 8 primarily to support lambda expressions. The designers (cleverly, in my view) decided to make lambdas syntax for creating anonymous implementations of an interface. But given lambdas can only implement a single method they would be limited to interfaces with a single method which would be a pretty severe restriction. Instead, default methods were added to allow more complex interfaces to be used.
If you need some convincing of the claim that default was introduced due to lambdas, note that the straw man proposal of Project Lambda, by Mark Reinhold, in 2009, mentions 'Extension methods' as a mandatory feature to be added to support lambdas.
Here's an example demonstrating the concept:
interface Operator {
int operate(int n);
default int inverse(int n) {
return -operate(n);
}
}
public int applyInverse(int n, Operator operator) {
return operator.inverse(n);
}
applyInverse(3, n -> n * n + 7);
Very contrived I realise but should illustrate how default supports lambdas. Because inverse is a default it can easily be overriden by a implementing class if required.
A new concept is introduced in Java 8 called default methods. Default methods are those methods which have some default implementation and helps in evolving the interfaces without breaking the existing code. Lets look at an example:
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork() {
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements SimpleInterface {
#Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
and the output is:
Do Some Work implementation in the class
DoSomeOtherWork implementation in the interface
Something that was overlooked in the other answers was its role in annotations. As far back as Java 1.5, the default keyword came about as a means to provide a default value for an annotation field.
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface Processor {
String value() default "AMD";
}
It usage was overloaded with the introduction of Java 8 to allow one to define a default method in interfaces.
Something else that was overlooked: the reason that the declaration default class MyClass {} is invalid is due to the way that classes are declared at all. There's no provision in the language that allows for that keyword to appear there. It does appear for interface method declarations, though.
Default methods in an interface allow us to add new functionality without breaking old code.
Before Java 8, if a new method was added to an interface, then all the implementation classes of that interface were bound to override that new method, even if they did not use the new functionality.
With Java 8, we can add the default implementation for the new method by using the default keyword before the method implementation.
Even with anonymous classes or functional interfaces, if we see that some code is reusable and we don’t want to define the same logic everywhere in the code, we can write default implementations of those and reuse them.
Example
public interface YourInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements YourInterface{
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
#Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Main method
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
The new Java 8 feature (Default Methods) allows an interface to provide an implementation when its labeled with the default keyword.
For Example:
interface Test {
default double getAvg(int avg) {
return avg;
}
}
class Tester implements Test{
//compiles just fine
}
Interface Test uses the default keyword which allows the interface to provide a default implementation of the method without the need for implementing those methods in the classes that uses the interface.
Backward compatibility:
Imagine that your interface is implemented by hundreds of classes, modifying that interface will force all the users to implement the newly added method, even though its not essential for many other classes that implements your interface.
Facts & Restrictions:
1-May only be declared within an interface and not within a class or
abstract class.
2-Must provide a body
3-It is not assumed to be public or abstract as other normal methods used in an interface.
A very good explanation is found in The Java™ Tutorials, part of the explanation is as follows:
Consider an example that involves manufacturers of computer-controlled cars who publish industry-standard interfaces that describe which methods can be invoked to operate their cars. 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.
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.
Default methods enable you to add new functionality to the interfaces of your apps. It can also be used to have a multi inheritance.
In addition to default methods, you can define static methods in interfaces. This makes it easier for you to organize helper methods

Java instance vs Abstract Classes and methods

I am new to Java and have been reading up on its main topics. I recently covered abstract classes and instances. I have read their definitions so its not a definition i am looking for.
I need help understanding why I would need to use an interface. All the examples I have seen of interfaces on java tutorials online to me seem like they can be implemented using an abstract class/method combination instead.
Is there a common scenario where only an interface can be used to solve the issue and a combination of abstract class/method would not?
A good example from the Java APIs is the LinkedList class.
As you can see from the link, it implements both the List and the Deque interfaces (as well as a few others), allowing it to be used whenever one or the other is needed. This would not have been possible using only abstract classes.
An interface defines a new secondary
datatype in Java.
It (interface) is a group of final variables
and abstract methods only.
The members of an interface are "public"
by default. Infact private and protected
modifiers are not allowed in an interface.
An interface is a reference type only
its objects cannot be created.
An interface can inherit another interface
but cannot inherit any class.
A class cannot inherit any interface but
it (a class) can implement zero to many
interfaces.
If a class implements interfaces then
1) It has to override all the abstract
methods of all the implemented interfaces.
2) Type compatibilty gets created between
the interface and the class. It allows an
interface reference can refer to object
of implementing class.
interface Iface
{
int x = 3;//final and public by default
void f();//abstract and public by default
}
interface AnotherI extends Iface
{
//more declarations possible here
}
class InterfaceDemo implements Iface
{
public void f()
{
int i;
for(i =0 ; i< x; i++)
System.out.println("Interfaces are widely used");
}
public static void main(String args[])
{
Iface ref = new InterfaceDemo();
ref.f();//allowed
//ref.newMethodsOfClass();//not allowed
}
}
The main difference is that you can only extend one class but you can implement multiple interfaces.
This can be important if you want to (for example) implement a listener while also extending another class. Note though that in many cases you are better off using an anonymous inner class to do the listening.
Java does not support polymorphic inheritance - where a class can extend multiple classes. This choice was made to avoid the problems associated with hierarchical conflict resolution (where a method exists in both parent classes - which one do you use?). In simple parlance, in java there can only be one "is a" relationship.
However, to allow a form of polymorphism, interfaces were introduced. These are hollow templates for which the class must provide implementations, and offer a way of creating a "look like a" relationship. While only allowing an object to "be" a instance of one (parent) class, it may "look like" any number of interfaces.
By taking inheritance out of interfaces, it allows cross-cutting concepts to be handled - ie where classes of completely different inheritance structures may nevertheless share some abstract similarity. A good example from the JDK is Serializable, which is a marker interface (one without methods). Virtually any class has the possibility to be serializable, but virtually all serializable classes don't share any of their inheritance hierarchy. This concept couldn't be handled with abstract classes - you have to step out of the class hierarchy to achieve it - ie interfaces is the only way to do it.

java traits or mixins pattern?

Is there a way to emulate mixins or traits in java? basically, I need a way to do multiple inheritance so I can add common business logic to several classes
Not the way you want to do it. Effective Java recommends that you "Favor composition over inheritance". Meaning you move the common logic to other classes and delegate. This is how you get around the lack of multiple inheritance in java.
I would encapsulate all of the business logic into a new class BusinessLogic and have each class that needs BusinessLogic make calls to the class. If you need a single rooted heirarchy for your classes that make calls to BusinessLogic, you'll have to create an interface as well (BusinessLogicInterface?)
In pseudo-code:
interface BusinessLogicInterace
{
void method1();
void method2();
}
class BusinessLogic implements BusinessLogicInterface
{
void method1() { ... }
void method2() { ... }
}
class User
extends OtherClass
implements BusinessLogicInterface
{
BusinessLogic logic = new BusinessLogic();
#Override
void method1() { logic.method1(); }
#Override
void method2() { logic.method2(); }
}
This isn't the prettiest implementation to work around a lack of multiple inheritance and it becomes quite cumbersome when the interface has a lot of methods. Most likely, you'll want to try and redesign your code to avoid needing mixins.
Is the object-purist stirring in you today?
Think you could do with a little composite oriented programming?
Then you, sir, are looking for Apache Polygene (formerly named Qi4J, then it renamed to Zest and/or Apache-Zest) ;)
Update 2022; It's discontinued currently, but useful anyway.
Java's answer to multiple inheritance is the ability to implement multiple interfaces. Of course, this means you'll get the method declarations, but not the logic.
You could try emulating mixins by composition: your Java class could define member variables that represent other classes that perform some common business logic.
In designing Java classes, I have not found the lack of C++ style multiple inheritance to inhibit the design of my architecture. You will find a way to achieve what you want to do.
QI4J allows you to use mixins
You can exploit the fact that interfaces allow nested classes (automatically public static) to keep the default implementation of the interface methods encapsulated within the interface itself. I.e. move the BusinessLogic class of Alex B's example inside the interface.
This is similar to the way Scala generates the JVM code for traits as explained here How are Scala traits compiled into Java bytecode?
When doing this the example becomes:
interface BusinessLogicInterface {
void method0();
class DefaultImpl {
private DefaultImpl() {
}
public static void method1(BusinessLogicInterface self) { ... }
public static void method2(BusinessLogicInterface self) { ... }
}
void method1();
void method2();
}
class User extends OtherClass implements BusinessLogicInterface {
#Override
void method0() { ... }
#Override
void method1() { BusinessLogic.defaultImpl.method1(this); }
#Override
void method2() { BusinessLogic.defaultImpl.method2(this); }
}
Note that we pass an object of the interface type as the "self" parameter. This means the business logic can use other abstract methods (method0). This can be very useful for creating a trait with abstract methods that are all orthogonal to each other and utility "extension" methods that may be implemented in terms of these orthogonal methods.
The drawback is that each interface must copy/paste the boilerplate delegation code. Another often used pattern in Java without this drawback (but with less cohesion and less OO way to call the methods) is to create a class with the plural name as the interface containing the static methods, this is used in the Collections utility class.
As of Java-8, default interface methods were added. This, together with multiple inheritance of interfaces in Java should allow some sort of mixin. Clearly the interfaces have to operate independently. So, there will be significant limitations.
Implementing simple mixin/traits support in java using CGLib/javassit is quite easy.
You can take a look for instance here for small example.
More complete, ready to use solution might be found: here

Categories

Resources