This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
If I have a class that extends ClassB and I want it to also be able to be a ClassC, but ClassC is a class not an interface, is there any way to "implement" ClassC's interface? So that someone could cast my object to ClassC (like when casting to an interface)?
Java doesn't support multiple inheritence. Interfaces are the way around it. You should change your design to use at least one interface. For example, you could move the methods of ClassC to InterfaceC. Then ClassC implements InterfaceC and ClassA extends ClassB implements InterfaceC. HTH Layne
Unfortunately, no. If an interface were already defined for Base, then OK - but if Base is a class with no interface, you're kind of stuck with it. I don't really understand how the various things you've ben asking about fit together, but from what I've gathered you're stuck with one or more existing classes that don't do what you need them to, and you're looking for ways to fix this. I don't really know about BCEL; maybe there's a way there. But one alternative you might look at is using something like JAD to decompile the class files of this evil base class you're stuck with - then refactor it to do your bidding, and recompile. This assumes that the only reason you haven't already done this is because you don't have access to the source code. If there are other problems (like other users might want to update the EvilBaseClass when a new version comes out) then this won't work so well. But I thought I'd toss the idea out there...
from what I've gathered you're stuck with one or more existing classes that don't do what you need them to
That's exactly right! My problem? The class is java.lang.System (among others). Basically, I'm trying to create a situation where I can not only have two applications run isolated in the same VM (I think I've got that "mostly" figured out), but to be able to act as full Java apps, i.e. each have their own security manager, policy, etc. I figured out a way to do it (using ThreadGroups, DomainCombiner and my own SecurityManager that can return the rpoper one) but I'd need to modify System and a few other classes. That's where all my weird questions are coming from. For example, the getSecurityManager() method, I was going to modify so it instead returned, MySecurityManager.getContextSecurityManager() which would return the security manager that app chose to install (with some byte-code re-engineering by me on its methods to ensure it "played nice."). But of course that's out, since once that's gone to defineClass() I'm out of luck. So I have been trying to "think outside the box" of other things I could do, like: when a class implicitly (or explicitly) loads System (say in a call like: System.getProperty(...) ), it calls my ClassLoader's method loadClass (I set it as the system classloader). In load class, I thought maybe I could generate a new class that "implemented" the interface of System (since it's a final class) so it could be cast to System and I'd return that to the caller instead (and it would delegate alot of work to java.lang.System). But it appears, no such luck. Any ideas?
Robert, that's an interesting idea. Java doesn't support it but it is interesting. There would have to be a few things ironed out such as could you implement the interface of a final class?
Tom, I haven't done C# since Beta 1 (I'll go into that in a minute), so I don't remember clearly, but I think something like this was available? Not for a final class specifically, but implementing the interface of a class? I could be making this up. I think it would be very useful, BUT I do understand how a final class should be just that. So even with being able to implement the interface of a class, you still wouldn't be able to on a final class (now if only people wouldn't write limited classes as final ) I feel final is a two-edged sword. 1. It's great because I stop myself (accidentally/absentmindedly) and others from creating another implementation when I mean it to be a singleton or the FINAL class. BUT...2. Doesn't everything that seemed perfect at one time end up being limiting eventually? There's always things we never imagined, and when your class is final, you're limited in the changes/adaptations you can make without ripping apart your entire API/structure. Especially when you program to it being final. Oh, so the C#? Well, when Beta 2 hit I was excited to get to it and was devastated when I discovered that the file system was out. It was instead using the Web Storage System. Now I don't know if you've used that before, or know much about it, but let me give you a good shudder: .Net (at that time, haven't followed it since) was going to move toward the web storage system, which...is one enormous database holding ALL your code (encoded) with ONE entry - a JET engine!! At that moment, I knew the extreme desire for MS to make everything proprietary and protected was too much for them. C# is neat, but I loved Java anyways and to base the NEW, Ultra-Modern, Better than Java system on a Jet-Engine driven storage system was a sad indicator. (Exchange uses it - ask a Network Admin who's worked with it and they'll spew lots of angry comments). (That's not to say I'm unwilling to learn from C#. Not even close. I think that MS has done some great things with it, I'm just going to use those to make Java, and my use of it, better) [ February 14, 2003: Message edited by: Robert Paris ]
Joined: May 05, 2000
As to the C#: C# doesn't support using a class as an interface. The Jet didn't make it out of beta 2.
Joined: Jul 28, 2002
Tom, Too bad it doesn't support that either. As for the Jet - that's good news, but frankly I'm sticking with Java for now. I see no benefit to me in switching. Especially since all the problems I'm having would exist in C# too. What about my other questions. You wouldn't happen to have an answer to that for me? I'm struggling here, convinced there's an answer (when the answer is probably, "Can't be done," which I hate to hear). Someone suggested nand-ing the midifier "final" of the System class so I could extend it, but I'm not sure that would work. Wouldn't the final definition still exist in the VM? Could I actually define a class extending it without that modifier and pass it to the VM and it would allow it through? (That would, I believe solve my problem)
Sounds like you might as well right your own JVM. It seems to me the following is theoretically possible... You examine classC and generate an interface for it (and load it into the JVM). You then modify the bytecode of the child class (who extends classB) to implement this newly generated interfaceC. Class C won't know that it implaments interfaceC (unless you explicitly change the class bytecode for classC and reload it), but that may not matter. --Mark
Joined: Jul 28, 2002
true, except the class I want to do that with is in rt.jar. It's from the bootclasspath.
Originally posted by Gopi Balaji: Is that not what almost every application server does?
Not to the extent that Robert wants; the applications in an application server are loaded using different classloaders and won't see each other's classes, but they do share one copy of the application server and system classes. Robert wants each application to get its own copy of the system classes as well, or something very close to that. - Peter