开发者

How do I implement multiple inheritence in Java

I'm working with a certain API library in Java. It has a base class A, as well as B and C which both extend A. B & C pr开发者_StackOverflowovide similar but distinct functionality, all three classes are in the library.

public abstract class A
{
    virtual foo();
}

public class B extends A {}
public class C extends A {}

How do I get elements of A, B, and C in my class? If I use interfaces to implement the classes, there is a lot of duplicate code, and inner classes will not allow me to override existing methods so that the calling interfaces of A, B, and C are preserved.

How do I implement multiple inheritence in Java?

EDIT: Thanks for edit George, its more clear now, forgot to mention one critical requirement: my classes must have A as a base so that they can be managed by platform API.


To recap, you have:

class A
{
    public void foo() {}
}

class B extends A
{
    public specificAMethod() {}
}

class C extends A
{
    public specificCMethod() {}
}

The above classes are in a library that you can't access or modify. You want to get the behaviour of both B and C in a third class D, as if it were possible to write:

class D extends B, C
{
}

Right?

What about using B and C instead of inheriting? Do you really need inheritance? You want to call private B and C methods?

class D
{

private B b;
private C c;
}


If you take the general approach of "Prefer Composition over Inheritance", you may find out that one or both of the classes shouldn't be actually "Inherited" anyway. In both cases, do the classes have a strict "is-a" relationship? If you can say "Has-a" out loud and it doesn't sound stupid, you probably want composition.

For instance, if you are implementing a deck of cards, the 3 of spades is-a 3 and it is-a spade, but you can also think of it as it has-a 3 and it has-a suit (spade). Since you can think of it that way, you should probably prefer the has-a interpretation and use composition.

Try to stay away from inheritance trees more than a few objects deep--and if you ever feel the desire to use multiple inheritance, try to work around it. This is one of the cases where Java kind of forces you to design your code to be a little more readable by not supplying a feature (but admittedly when you really want it, it's not there and that can hurt! Some level of mixin would be nice).


Sounds like you want to extend A - call it D - override its foo(), and then have new subclasses E & F that extend D and add their own functionality.

You might think about extracting common interfaces and reusing those. A good IDE with refactoring capability will make it easy to do.


Multiple class inheritance is not possible in Java, however you can use multiple inheritance for interfaces. Using Delegation pattern you can combine behavior of several other classes into one.


Completely different approach is applied in COM: all objects inherit from IUnknown, which has a method that could be translated to Java as:

Object queryInterface(Class<?> clazz)

The simplest implementation of this method can be:

if(clazz.isAssignableFrom(this.getClass()))
    return this;
else
    return null;

Where single inheritance won't work, it's just enough to add:

else if(class == SomeClass.class) {
    return something;
} else ...

This way even most complex multiple inheritance cases can be tackled and you get full control over what is returned and when, so you avoid many problems with 'classical' multiple inheritance from languages like C++, like fork-join problem.


Since Java 1.8 you can use interfaces with default methods. It's very handy and I tend to use it a lot. Covariant return types are supported, too. There are a fiew restricktions (see below), but you dont have to implement the inheritence by your self and let the compiler work for you.

public interface A {
    default A foo() {
        return this;
    }
}

public interface B extends A {
    @Override
    default B foo() {
        return this;
    }
}

public interface C extends A {
    @Override
    default C foo() {
        return this;
    }
}

public interface D extends B, C {
    @Override
    // if the return type does not implement B and C
    // the comiler will throw an error here
    default D foo() { 
        return this;
    }
}

Note that this but note that you cant call super.foo or define fields or private members (until Java 9) since its still interfaces. If you get along with this restrictions, this opens up you a new level of object oriented programming.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜