Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implementing interfaces after the fact

I think, the following can't be done in Java. But I would be happy to learn how to implement something that resembles it.

Suppose we have a class C, that is already used in compiled code. (We can neither change that code nor the original definition of C).

Suppose further there is interesting code that could be re-used, if only C would implement interface I. It is, in fact, more or less trivial to derive D that is just C + the implementation of the interface methods.

Yet, it seems there is no way, once I have a C, to say: I want you to be a D, that is, a C implementing I.

(Side remark: I think the cast (D)c, where c's runtime type is C, should be allowed if D is a C and the only difference to C are added methods. This should be safe, should it not?)

How could one work around this calamity?

(I know of the factory design pattern, but this is not a solution, it seems. For, once we manage to create D's in all places where formerly were C's, somebody else finds another interface J useful and derives E extends C implements J. But E and D are incompatible, since they both add a different set of methods to C. So while we can always pass an E where a C is expected, we can't pass an E where a D is expected. Rather, now, we'd need a new class F extends C implements I,J.)

like image 964
Ingo Avatar asked Apr 15 '09 14:04

Ingo


1 Answers

Couldn't you use a delegate class, i.e. a new class which wraps an instance of "Class C", but also implements "Interface I" ?

public class D implements I {

    private C c;

    public D (C _c) {
        this.c = _c;
    }

    public void method_from_class_C() {
        c.method_from_class_C();
    }
    // repeat ad-nauseum for all of class C's public methods
    ...

    public void method_from_interface_I() {
        // does stuff
    }
    // and do the same for all of interface I's methods too
}

and then, if you need to invoke a function which normally takes a parameter of type I just do this:

result = some_function(new D(c));
like image 63
Alnitak Avatar answered Sep 29 '22 23:09

Alnitak