Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!.POSTED!not-for-mail From: Lew Newsgroups: comp.lang.java.programmer Subject: Re: Partially overriding a method? Date: Thu, 21 Apr 2011 12:42:17 -0400 Organization: albasani.net Lines: 174 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.albasani.net EkJ7dVXnQVx/2NnQTjjhccjdP0+1JtsQWQWMAqnAmv8yPZai5Qvy7CNAPgyYtds+ZO4/95wEjC6jBJ4+/KuNdwt/BAh9V4fB0Edb/qjAXJ/NhHl1ayQIt6MSAjdMtrZp NNTP-Posting-Date: Thu, 21 Apr 2011 16:42:09 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="Rqi+rIHhMYpZNuCDTh8pFiV1xvmGOlMnAeDk8OqiQRMCWLzlIWq13bLZu6H5q/QrzkmvX7+vUEz4KxnaQXTK0W8f5J8JpZ5pFIw4igHpttsHtz0CVLdjC4nmZvHMm8ul"; mail-complaints-to="abuse@albasani.net" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8 In-Reply-To: Cancel-Lock: sha1:qQefo91Y5nsu8E5763j3k36FyJo= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3186 On 04/21/2011 11:31 AM, 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. You need to clean up your language. In Java there is no such thing as a "subclass of a method". Only classes have subclasses, or more generally, only types have subtypes. Imprecise descriptions lead to error. There is no such thing as "partially overriding a method" in Java. Use the '@Override' annotation in your code. It will help you see that a method either does or does not override another. It's binary, either-or, black-and-white, is-or-is-not. Predictably, verifiably, completely, utterly and as supported by '@Override', you can tell if a method is or is not an override. Period. > 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(String x) { > System.out.println("Sub class: " + x); > } > > } > > The call to mc.check() calls the main class's version of the method. You should use the '@Override' annotation. Attempting to use it on 'SubClass#check(String x)' would have shown you that it does not override 'MainClass#check(Object x)'. > However, if I change the sub-class to: > > class SubClass extends MainClass { > > void check(Object x) { > System.out.println("Sub class: " + x); > } > > } > > then it uses the sub-class always. Well, yeah. That's by design, yes? Again, you should use '@Override' here. The reason the invocation in your example calls the override is because that's the whole point of overrides! > One option would be something like: > > class SubClass extends MainClass { > > void check(Object x) { > if(x instanceof String) { > check((String)x); > } else { > super.check(x); > } > } > > void check(String x) { > System.out.println("Sub class: " + x); > } > > } > > This would override and only use the sub-class for processing Strings. Rather imprecisely phrased. If by that you mean, "'check(Object)' overrides, but the specialization 'check(String)' does not, therefore references to the latter through a 'SubClass' reference will not invoke the override," then you are correct. I took the liberty of turning your example into an actual SSCCE, something you should have done. I've also changed the class names so that the stupid compound part 'Class' is no longer part of them. package com.lewscanon.eegee; /** * DoesItOverride. */ public class DoesItOverride { /** * main. * @param args String [] argument array. */ public static void main( String [] args ) { DoesItOverride doesIt = new Rider(); Rider orider = new Rider(); System.out.print( "doesIt: "); doesIt.check( "Test doesIt" ); System.out.print( "doesIt: "); doesIt.check( Integer.valueOf( 7 ) ); // eschew autoboxing System.out.print( "orider: "); orider.check( "Test rider" ); System.out.print( "orider: "); orider.check( Integer.valueOf( 7 ) ); } /** * check. * @param x Object. */ public void check( Object x ) { System.out.println( "parent check(Object): "+ x ); } } class Rider extends DoesItOverride { @Override public void check( Object x ) { System.out.println( "subtype check(Object): "+ x ); } /** * check. * @param x String - not an override. */ // @Override /* ^^ Causes compilation error: The method check(String) of type Rider must override or implement a supertype method */ public void check( String x ) { System.out.println( "subtype check(String): "+ x ); } } Output: doesIt: subtype check(Object): Test doesIt doesIt: subtype check(Object): 7 orider: subtype check(String): Test rider orider: subtype check(Object): 7 -- Lew If you are still thinking in terms of "classes", you have much progress yet to make.