6

I have this working hierarchy already and the program runs as expected. Basically I have abstracted everything in a Base class and all other subclass adding their own methods.

abstract Class Base{
}

class A extends Base{
    //new methods
}

class B extends Base{
    //new methods
}

everything looks good until later (errr...new requirements) I realize I need to have a new class (lets call this class C) that extends both class A and B. Now, in java its not possible to extend two concrete class.

class C extends A, B{
    //new methods
}

I need both of the methods and variables in class A and class B but I dont know how to do this? Any hints on how do I do this change? I am not that good in design pattern so i thought of asking it here.

Thanks

UPDATE This is actually a JSF Managed Bean wherein I abstracted everything in a Base Managed Bean and all other subclass overriding/adding their own implementations on top of the base managed bean. There is just a new requirement that was added wherein I needed the functionality of both subclasses (A and B) into a new subclass (C)

Mark Estrada
  • 9,013
  • 37
  • 119
  • 186

4 Answers4

4

Refactor your code and make A and B and Base interfaces instead of classes and use interface inheritance instead of implementation inheritance.
Then you can implement both A and B (this is how multiple inheritance is supported in Java)

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 1
    In the question @Mark Estrada has mentioned "I need both of the methods and variables in class A and class B" So, I guess he cant change `A` and `B` to interfaces because they seem to have member variables. – codeMan Apr 16 '13 at 10:37
  • @codeMan:Member variables are not an issue. He just need to redesign his code properly. – Cratylus Apr 16 '13 at 10:39
  • 1
    And he would have to reimplement all of the methods instead of using existing code then. – Evan Knowles Apr 16 '13 at 10:40
  • 1
    So, If I make A, B and Base as interfaces then it means I need to add new concrete class to implement them? is this correct? I have no qualms about refactoring actually but I just need to know the best and possible way of solving this problem. Thanks for your reply. – Mark Estrada Apr 16 '13 at 10:45
  • The best way to design is using *interfaces*. Avoid implementation inheritance as much as possible as it tightly couples your code and make it affected by changes (you already are seeing the problems). Use implementation inheritance sparingly – Cratylus Apr 16 '13 at 11:06
3

Either use composition or use inner class.

class C extends A {
   B b = ... // this is one option

   class D extends B {
     // this is another option 
   }  
}
Sudhanshu Umalkar
  • 4,174
  • 1
  • 23
  • 33
2

Ideally you should create all the classes A, B and Base as interfaces, but as you have mentioned that above design was already implemented I am assuming that this is not an option now.

The other solution is to create an instance of type A or/ and B in the class C (composition).

Class C{
A a=new A();
B b=new B();
}

You can also use a mixed approach using both inheritance and composition like extend A and create instance of B.

Kamal
  • 5,462
  • 8
  • 45
  • 58
1

Lets C contain A and B but also make it extend Base then delegate so you don't have to duplicate anything.

class C extends Base
{
   A a = new A();
   B b = new B();

   // Now delegate any implemented methods from Base to A and B

   @Override
   public void anAbstractMethod()
   {
      a.anAbstractMethod();
      b.anAbstractMethod();
   }
}
The Cat
  • 2,375
  • 6
  • 25
  • 37