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.)
If all that you need to be compatible with is interfaces then no problem take a look at dynamic proxy classes, its basically how you implement interfaces at runtime in java.
if you need similar runtime compatibility with classes I suggest you take a look at cglib or javaassist opensource libraries.
Not at all. If you could make this cast, then you could compile code that attempted to call one of the "added methods" on this object, which would fail at runtime since that method does not exist in C.
I think you are imagining that the cast would detect the methods that are "missing" from C and delegate them to D automatically. I doubt that would be feasible, although I can't speak to the language design implications.
It seems to me the solution to your problem is:
Define class D, which extends C and implements I
Define a constructor D(C c) which essentially clones the state of the given C object into a new D object.
The D object can be passed to your existing code because it is a C, and it can be passed to code that wants an I because it is an I
Couldn't you use a delegate class, i.e. a new class which wraps an instance of "Class C", but also implements "Interface I" ?
and then, if you need to invoke a function which normally takes a parameter of type
I
just do this:I think you that can't do it because Java is strictly typed. I believe it can be done in languages like Ruby and Python with a usage of mixins.
As for Java it definitely looks like a good usage for the Adapter design pattern (it was already proposed earlier as a "wrapper" object).
If you (can) manage the
ClassLoader
that loads your classC
then you can try to do some class-loading time shenanigans with bytecode instrumentation to make the class implement the interface.The same can be done during build-time, of course. It might even be easier this way (as you don't need access to the ClassLoader).
I believe what you want is possible by using
java.lang.reflect.Proxy
; in fact I have done something similar for a current project. However, it's quite a bit of work, and the resulting "hybrid objects" can expose strange behaviour (because method calls on them are routed to different concrete objects, there are problems when those methods try to call each other).