-1

It seems that Java 8 allows full fledged inheritance with a simple framework as below, using Static and Default methods on interfaces.

While its always possible to misuse and write stupid code, these new features make it quite easy to achieve multiple inheritance, even if the designers of the language meant to stay away from it.

Is this a simple implementation of Multiple Inheritance using Interfaces as base classes, or a misuse of the language? Did Java designers go too far in allowing this?

package PseudoMultipleInheritance;
import java.util.HashMap;

abstract class InstanceMap<T,T2>
{ 
     HashMap<Object,Object> instances = new HashMap<Object, Object>();
     abstract T2 createMembersInstance();
     T2 getMembersInstance(T thisObject )
     {
         if ( !instances.containsKey(thisObject) )
             instances.put(thisObject,createMembersInstance());
         return (T2) instances.get(thisObject);      
     }  
}

interface A  
{
 class Members
 {
    int x;  // just an example of an inheritable member 
 }
 InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() {   A.Members createMembersInstance() {return new A.Members();  }};
 default A.Members thisA() { return instanceMap.getMembersInstance(this); }
 default int getX()
 {
     return thisA().x;  // // just an example of an inheritable getter
 }
 default void setX(int x)
 {
     thisA().x = x;  // just an example of an inheritable setter
 }
}

interface B 
{
 class Members
 {
    int y;  // just an example of an inheritable member
 }  
 InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() {   B.Members createMembersInstance() {return new B.Members();} };  
 default B.Members thisB() { return instanceMap.getMembersInstance(this); }
 default int getYLastDigit()
 {
     return thisB().y % 10;  // just an example of an inheritable function
 }
 default void incrementY(int x)
 {
     thisB().y += x; // just an example of an inheritable function
 }
}

class C implements A, B
{
}

public class Example04AlmostMultipleInheritance {

 public static void main(String[] args) {
     C c1 = new C();
     C c2 = new C();
     c1.setX(5);
     c2.setX(3);
     System.out.println(c1.getX());   // prints 5
     System.out.println(c2.getX());   // prints 3
     c1.incrementY(99);
     System.out.println(c1.getYLastDigit());  // prints 9 

}
}

///////////////////////////////////////////////////

Or for yet another option:

interface A  
{
 class Members
 {
    public int x;  // just an example of an inheritable member
    void showX() { System.out.println(x); }  // just an example of an inheritable function
 }
 InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() {   A.Members createMembersInstance() {return new A.Members();  }};
 default A.Members getA() { return instanceMap.getMembersInstance(this); }
}

interface B 
{
 class Members
 {
    int y;  // just an example of an inheritable member
 }  
 InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() {   B.Members createMembersInstance() {return new B.Members();} };  
 default B.Members getB() { return instanceMap.getMembersInstance(this); }
}

class C implements A, B
{
}

public class Example04AlmostMultipleInheritance {

 public static void main(String[] args) {
     C c1 = new C();
     C c2 = new C();
     c1.getA().x = 5;
     c2.getA().x = 3;
     c1.getA().showX();   // prints 5
     c2.getA().showX();   // prints 3
     c1.getB().y = 99;
     System.out.println(c1.getB().y % 10);  // prints 9 

}
}
Gonen I
  • 5,576
  • 1
  • 29
  • 60

3 Answers3

1

Implementing an interface is not inheritance. It's as simple as that.

what if someone implements both your interfaces but supplies a different implementation than the default one?

So no, this is not multiple inheritance, It's simply a way to write your code that depends on nobody actually implementing their own version of the default methods. Which means that it depends on people not actually using interfaces the way they're supposed to, because they are supposed to be able to implement their own methods instead of the defaults, but if they actually do that your "multiple inheritance" does not work as expected.

So I'd actually consider this to be misuse of the language.

Cedric Mamo
  • 1,724
  • 2
  • 18
  • 33
  • 1
    But isn't the problem with Java that now does not require you to implement methods on interfaces, thus nullifying the original meaning of the term? After all, people can also override methods in a base class, and it's still inheritance. – Gonen I Oct 08 '14 at 23:20
  • just because it doesn't require you to, doesn't mean that you can't. It just means that now you have a choice. But if you actually do utilize that choice, the program breaks. – Cedric Mamo Oct 08 '14 at 23:22
1

It is A form of multiple inheritance, but it's not the "Diamond Problem" that is usually brought up when discussing multiple inheritence. Java's implementation is almost the same as Scala's solution to the same thing, which is somewhat similar to how Python implements multiple inheritance.

Falmarri
  • 47,727
  • 41
  • 151
  • 191
  • Yes it looks like this handles the "Diamond Problem" correctly. The member access will go to the grandfather interface's accessor function, which then uses the static HashTable member defined on the grandfather interface. – Gonen I Oct 08 '14 at 23:38
0

no, see example of multiple inheritance here: http://java.dzone.com/articles/interface-default-methods-java

Ray Tayek
  • 9,841
  • 8
  • 50
  • 90