1

Say I have an abstract class A and an abstract class B:

abstract class A {
    public void doA(){
        //some stuff
    }
}

abstract class B{
    public void doB(){
        //some stuff
    }
}

Now I want to accomplish the following situation:

class C has functionality of just A
class D has functionality of just B
class E has functionality of both A and B.

How would I do that? Is that even possible in java, because one cannot extend multiple classes?

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • 1
    I would use a wrapper that has all methods and use instances of `A` and `B` behind the scenes, something like a `Facade` class. Indeed it heavily depends on your requirements to analyze the problem and see if there's a [GoF pattern](http://en.wikipedia.org/wiki/Design_Patterns) that provides a solution for it. – Luiggi Mendoza Feb 19 '13 at 19:42
  • Yes, I agree with Luiggi Mendoza. the tricky part is do you need polymorphism there, e.q. A a = new E() ? Then you will meed A and B to be interfaces or implement interfaces. – kofemann Feb 19 '13 at 19:46

4 Answers4

2

Java does not support multiple inheritance. If you wanted to have functionality from both A and B, you would have to declare at least one of them as an interface.

To get the functionality of just A, eg.

public class C extends A {
    //your methods
}

As others have put it, you the Facade pattern to have the functionality of both classes

Assuming A and B aren't abstract, since you cannot instantiate abstract classes.

public class Facade {
    private A mA = new A();
    private B mB = new B();

    private void doB() {
        mB.doB();
    }

    private void doA() {
        mA.doA(); // as long as these are visible
    }    
}
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • You could also use delegation or composition. But that requires extra work and doesn't interact well with protected/virtual members. – Antimony Feb 19 '13 at 19:40
  • But declaring one of them as an interface means I cannot provide the actual functionality in my methods, right? – nhaarman Feb 19 '13 at 19:41
  • The code example it's not a Decorator but Facade pattern. I recommend both you and OP read [Examples of GoF Design Patterns](http://stackoverflow.com/q/1673841/1065197) – Luiggi Mendoza Feb 19 '13 at 19:45
  • Fixed, I was talking about Decorator as a means to add functionality. But then that's not what he wants. He wants existing functionality from multiple classes -> Facade. – Sotirios Delimanolis Feb 19 '13 at 19:47
  • You can indeed use Decorator pattern to have more than 1 functionality from distinct classes and not having multiple inheritance. Please refer to the link provided in my comment to have a better understanding. – Luiggi Mendoza Feb 19 '13 at 19:48
  • Thanks, this makes sense. I could ofcourse instantiate my abstract classes `A` and `B` and redirect my methods? `A a = new A(){ void myAbstractMethod(){ E.this.myAbstractMethod();} };` – nhaarman Feb 19 '13 at 19:53
  • Yes, you can use Anonymous classes, but I don't find them nice to look at. – Sotirios Delimanolis Feb 19 '13 at 19:58
1

It is Polymorphism situation. You should use interfaces and adapter pattern to achieve this. Mkae sure your doB() and doA() are final methods in abstract class.

interface IA {
    public void doA();
}

interface IB {
    public void doB();}
}

abstract class A implements IA {
    public final void doA() { ... }
}

abtstract class B implements IB {
    public final void doB() { ... }
}

class C extends A {
}

class D extends B {
}

class E implements IA, IB {
    IA a = new C();
    IB b = new D();
    public void doA() { a.doA(); }
    public void doB() { b.doB(); }
}
Shivam
  • 2,134
  • 1
  • 18
  • 28
1

This is very similar to the other answers, but differes in that it does not attempt to instantiate an abstract class.

The three answers that are similar are all using Composition to solve the problem. One calls it a facade, another adapter. I call it proxy. I'm not sure which (if any) is correct. The important fact in all three is that we use Composition instead of inheritance.

Start by creating interfaces. For example:

public interface iA
{
  public void doA();
}

public interface iB
{
  public void doB();
}

Alter your abstract classes to implement these interfaces

abstract class A implements iA
{
  public void doA()
  {
    ... blah ...
  }
}

abstract class B implements iB
{
  public void doB()
  {
    ... blah ...
  }
}

Create concrete versions of A and B (here I do this as inner classes of C), implement both interfaces in C, and proxy the calls doA() and doB() from the C class to the concrete implementations.

public class C implements iA, iB
{
  private ConcreteA cA = new ConcreteA();
  private ConcreteB cB = new ConcreteB();

  public void doA()
  {
    cA.doA();
  }

  public void doB()
  {
    cB.doB();
  }


  private class ConcreteA extends A
  {
    public doA()
    {
      ... blah ...
    }
  }

  private class ConcreteB extends B
  {
    public doB()
    {
      ... blah ...
    }
  }
DwB
  • 37,124
  • 11
  • 56
  • 82
1
abstract class A {
    public void doA(){
        // some stuff
    }
}

abstract class B{
    public void doB(){
        // some stuff
    }
}
class C {
    private A a; // assume getter/setter methods or constructor for initialization
    public void doA()
    {
        a.doA();
    }
}
class D {
    private B b;// assume getter/setter methods or constructor for initialization
    public void doB(){
        b.doB();
    }
}
class E{
    private A a;// assume getter/setter methods or constructor for initialization
    private B b;// assume getter/setter methods or constructor for initialization
    public void doAB(){
        a.doA();
        b.doB();
    }
}

I would suggest you to study more on abstract class and interface. To understand above code you need to understand "Strategy Pattern". After reading "Strategy Pattern" you will be able to modify my given code in more granular level. I haven't done coding for interface as it would have created more complex thing to understand.

Read "Strategy Pattern" in "Head First Design Patter"

AmitG
  • 10,365
  • 5
  • 31
  • 52