Inheriting from two Java classes
I know Java forbids inheriting from multiple classes and allows implementing any number of interfaces. However, while inte开发者_开发百科rfaces are good for polymorphism, they cannot contain any actual code that their subclasses may want to share. What if I have two different superclasses that have shared code that I want to use in my subclass?
Example: In my program, there are two superclasses, one that works with HashMaps and one that works with Strings, and both have direct subclasses, and all is fine there. But now I have a third that requires the shared functions of both superclasses, but it can only extend one. Is there an easy way to redesign this class structure without having to duplicate a lot of code?
Use delegation rather than inheritance:
public class Third implements FirstInterface, SecondInterface {
private First first;
private Second second;
public void foo() {
first.foo();
}
public String bar() {
return second.bar();
}
}
I've seen this done by
- Extracting an interface from both of the superclasses
Creating a class that implements the interfaces, then delegating all calls to the actual objects
public interface IFirst { public void foo(); } public interface ISecond { public void bar(); } public class Third implements IFirst, ISecond { private IFirst first; private ISecond second; public Third(IFirst first, ISecond second) { this.first = first; this.second = second; } @Override public void foo() { first.foo(); } @Override public String bar() { return second.bar(); } }
This will not give you access to the protected members in the class heirarchy. If that is what you are looking for, you're out of luck in Java. However, this will allow you to refer to this object as both IFirst and ISecond using polymorphically. Thus, you'll be able to access it in external code that requires either one of the two types.
Note: I stole the naming from JB.
Use composition -- basically make your new class extend one of the classes and have a member variable in the new class that is of type superclass 2. Or you could just go the whole hog and use composition on the new class and have class1 and class2 type members in them
I question any design where you have that much interdependency between classes that manage hashmaps vs classes that manage strings. But to answer your question directly, you can make your third class a Facade that wraps instances of both your superclasses, then make its methods delegate to those classes as appropriate.
One approach to this problem is to favor composition over inheritance. If you can design the two classes that you currently want to extend from so that they can be used as members of your new class, then you should have the flexibility you need. Instead of
class MyClass extends MapBehavior, StringBehavior { ... }
try
class MyClass {
MapBehavior mb;
StringBehavior sb;
...
}
精彩评论