3

It's hard to explain, but it's simple to show a snippet of Ruby code:

Have two modules that implement methods:

module Foo
    def one
        print "ONE!"
    end
end

module Bar
    def two
        print "TWO!"
    end
end

Have a class that includes them:

class Test
    include Foo
    include Bar
end

Now your class Test can call those two methods.


As far as I'm aware, there isn't something like this in Java. Close concepts would be:

Multiple inheritance

Which is not supported by Java.

Interfaces

They're method contracts - there is no implementation. Your class Test would need to implement the methods itself, and that's what I want to avoid. Simply for the sake of not writing the same code twice (I have several other classes, some of them may want to implement those methods too).

Abstract classes

I'd still need to inherit from two classes at the same time.


So what is the recommended solution here?

Saturn
  • 17,888
  • 49
  • 145
  • 271
  • You should also consider composition. Its well explained here: http://stackoverflow.com/questions/7230661/how-to-create-a-class-that-extends-two-existing-concrete-classes – Kasper Ziemianek May 30 '14 at 09:30
  • 2
    The need for multiple inheritance is often a sign of a flaw in the design. If you explain more concretely why you are tempted to do this, we might be able to suggest more concrete solutions. – Thomas May 30 '14 at 09:34

5 Answers5

5

In Java 8 you could achieve this using default methods but that was never the intent of defaults so this may be bad advice:

interface Foo {
    default void one () {
        System.out.println("ONE!");
    }
}

interface Bar {
    default void two () {
        System.out.println("TWO!");
    }
}

class FooBar implements Foo, Bar {

}
public void test() {
    FooBar fooBar = new FooBar();
    fooBar.one();
    fooBar.two();
}

However, I would like to reiterate what @Thomas said in his comment The need for multiple inheritance is often a sign of a flaw in the design.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • aren't static methods a better choice if using java 8 ? – NimChimpsky May 30 '14 at 09:37
  • @NimChimpsky: Is there something new about static methods in Java 8, too? (default methods are new in Java 8, so that option just was not available before) – Thilo May 30 '14 at 09:40
  • @NimChimpsky - I don't see how - perhaps you could post an alternative answer. – OldCurmudgeon May 30 '14 at 09:40
  • @Thilo see my answer, static methods on interfaces just getted added to class that implements them (but they have to be referenced by the interface). They have the drawback of being static – NimChimpsky May 30 '14 at 09:41
  • @NimChimpsky: I see. What do they do with name clashes here? – Thilo May 30 '14 at 09:43
  • As long as you don't mix state in the "inheritance", then you're fine with this approach. – skiwi May 30 '14 at 09:52
3

Favour composition over inheritance. So your class would have references to both implementing classes.

MyClass {
    ClassA
    ClassB
}

Th alternative of subclassing twice, seems rather hacky to me and would lead to an unnecessarily complex inheritance tree.

Or with java 8's new static methods (as opposed to default which can be overridden). See comparator for examples.

    interface X
    {
       static void foo()
       {
          System.out.println("foo");
       }
    }
 interface Y
    {
       static void bar()
       {
          System.out.println("bar");
       }
    }
 MyClass implements X, Y {
   public static void main(String args[])
   X.foo();
 }

The interface name must be used as prefix, as static method is part of interface.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • But then I'd still have to implement new methods in my classes designed to access such fields anyway, right? – Saturn May 30 '14 at 09:33
3

The easiest solution is to create hierarchical inheritance as so :

public class foo
{
    public void one()
    {
        System.out.println("ONE!");
    }
}


public class bar extends foo
{
    public void two()
    {
        System.out.println("TWO!");
    }
}

class Test extends bar
{
    //this class now has access to both methods from the two classes
}
Alex Barac
  • 632
  • 4
  • 12
0

There are few solutions that might solve your case. You can use the Visitor Pattern or Strategy Pattern.

In both cases you will benefit from Interfaces and Composition.

0

Your class Test would need to implement the methods itself, and that's what I want to avoid.

Well, yes, but that "implementation" could just be a simple delegation (and your IDE can create the code for this wrapper automatically).

 public String one(){
    return foo.one();
 }

The actual code can be in class Foo, and be shared (as in "used") among many classes.

Thilo
  • 257,207
  • 101
  • 511
  • 656