Re: Partially overriding a method?
markspace wrote:
raphfrk@gmail.com wrote:
I was wondering if it is possible to override a method but only for
certain sub-classes of the method that the super-class supports.
Yes and no. As you discovered, overriding is all or nothing. You either
override or you don't.
But you could add your own processing to do what you want with the "super"
keyword.
<http://download.oracle.com/javase/tutorial/java/IandI/super.html>
For example:
class MainClass {
public static void main(String[] args) {
System.out.println("Started");
MainClass mc = new SubClass();
mc.check("Testing");
mc.check(7);
}
void check(Object x) {
System.out.println(x.toString());
}
}
class SubClass extends MainClass {
void check(Object x) {
if( x instanceof String ) {
System.out.println("Sub class: " + x);
} else {
super.check( x );
}
}
}
The code changes above are untested.
The presence of the 'instanceof' operation is often a red-flag marker of bad
design.
Polymorphism handles type resolution automatically. Doing it manually like
this is a big oops. Josh Bloch and other writers warn against overload
resolution on subtypes - it can be dicey.
If you have a concept that a particular method overload should be an override,
but the parent class doesn't sport that overload, you're trying to assert two
contradictory things. You're trying to say that 'check(String)' is an
override but that it isn't. As a result, you have to do funky type checks in
the subtype.
The upside is that you get what the OP asks for, if not what he wants - an
override that can specialize for a covariant argument type. The idiom in the
SSCCE I posted, as the output shows, will not treat 'check(String)' as a
specialization if the variable is of the supertype - the compiler will invoke
the 'check(Object)' form no matter what. It only knows about the
specialization through a reference of the subtype.
I'm not saying that the 'instanceof' dodge is a bad way to bandage an
infelicitous design, only that its necessity stems from such a decision.
Either 'check(String)' is part of the supertype contract or it isn't; trying
to pretend that it is via subtype magic is not a great thing. You could just
add the specialization to the parent type, or abandon the idea that you should
have a specialization at all. Or perhaps abandon the idea that you should
have a generalization in the supertype. OR ... you could make the
specialization a generics parameter:
public class DoesItOverride <T>
{
public void check( T x )
{
System.out.println( "Supertype: "+ x );
}
}
class Rider extends DoesItOverride <String>
{
@Override
public void check( String x )
{
System.out.println( "Subbatype: "+ x );
}
}
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg