tags:

views:

489

answers:

9

Let's have the following class hierarchy:

public class ParentClass implements SomeInterface {
}

public class ChildClass extends ParentClass {
}

Then let's have these two instances:

ParentClass parent;
ChildClass child;

Then we have the following TRUE statements

(parent instanceof SomeInterface) == true
(child instanceof SomeInterface) == true

Is it possible to unimplement the SomeInterface in the ChildClass, so when we check with the instanceof operator it returns false?

If not possible, is there a workaround?

+2  A: 

It's not possible and doing so would violate the implied IS-A relationship between ChildClass and ParentClass. Why do you want to do this?

John Topley
A: 

Maybe you have a specific case where a better solution could be devised, but for the generic case you need some black magic. Eventually Javassist could be used "hack" your objects but I'm not so sure.

divideandconquer.se
+1  A: 

I don't think you can "unimplement" it but you could check if it is an instance of the parent class. Is the interface yours? If so you could extend it to include an "IsObjectDerived" method with semantics that it returns true iff the class only derives from object. Since you are writing the class all you would need to do is implement it in the parent and have it return true if the object is of class Parent and false otherwise.

You could also do this with reflection by checking the superclass of the current class and make sure it is object. I'd probably do it this way since then implementing classes can't lie. You may want to look a tutorial on reflection in Java that I found.

[EDIT] In general I agree that this seems unnecessary in a reasonable design, but it can be done.

tvanfosson
A: 

I think you should take this problem as a clear indication that your interface and class design is flawed. Even if you could do it in Java (and I don't think you can) you shouldn't.

How about re-factoring ParentClass so you have the SomeInterface implementation separate from that which you want in ChildClass. Maybe you need a common base class for ParentClass and ChildClass.

Simon
+18  A: 

No it is not possible, and your intent to do so is a good hint that something is flawed in your class hierarchy.

Workaround: change the class hierarchy, eg. like this:

interface SomeInterface {}
abstract class AbstractParentClass {}
class ParentClass extends AbstractParentClass implements SomeInterface {}
class ChildClass extends AbstractParentClass {}
+7  A: 

Maybe composition instead of inheritance is what you want, i.e. have a "base class" object as a member and just implement the interfaces you need, forwarding any methods needed to the member.

OregonGhost
A: 

I fail to see how this would be sound practice, but you could alter a class dynamically using the excellent package Javassist created by Shigeru Chiba et al. Using this, you can add and remove features from classes and then use instances of these classes without saving as classfiles.

Dynamic, interesting and totally confusing for anyone else. Use with care is my advice, but do play around with it as it makes you a better programmer in my opinion.

(I believe ASM works in a similar fashion, but I have not tried it so far. It does seem to be very popular amongs the non-java language creators working on the JVM, so it is probably good.)

+2  A: 

I agree with other answers that it is not possible in Java.

The other answers further suggest it shows a flaw in your design.

While I agree with them, it is only fair to point out that some prominent OO experts (particularly Bertrand Meyer) disagree with us, and believe such a design should be allowed.

Other OO inheritance models (notably, Meyer's Eiffel programming language) do support the "Change of Availability or Type" (CAT) feature that you are looking for.

Oddthinking
+1  A: 

Since inheritance, the basis of OOP polymorphism, denotes an is-A relationship - your question seems to request a way to redefine "is" relationships to be "is not" relationships.

That won't work.

Go back to some introductory object-oriented texts or online material and study what object-oriented means: polymorphism, encapsulation, and identity.

  1. Strip off identity, and you've got COM/ActiveX and stolen credentials.
  2. Strip off encapsulation and nobody is safe.
  3. Strip off polyphism's type rules and you basically have nothing is necessarily what it says it is.

If you want a situation like that, then program in "C". Don't mess around with pretending to write OOP code using OOP language features. Just use struct to hold your data. Put unions everywhere. Use typecast with abandon.

Your program likely will not work reliably but you will be able to circumvent any restrictions languages like Java and C++ have introduced to make programs more reliable, easier to read, and easier to write/modify.

In a dynamic programming language like SmalTalk or Python, you can essentially rip the wings off a butterfly at runtime. But only by changing/corrupting the type of the object.

Doing so does not buy you anything. There are coding/design techniques and design patterns that let you accomplish any "good" result that you might be after that are similar to this.

It is best if you think of what exactly you are trying to do in your application, and then try to find the safest/simplest way to accomplish that using sound techniques.

JohnnySoftware