c# - Abstract methods and the Open-Closed principle -


suppose have following contrived code:

abstract class root {   public abstract void printhierarchy(); }  class level1 : root {   override public void printhierarchy()   {     console.writeline("level1 child of root");   } }  class level2 : level1 {   override public void printhierarchy()   {     console.writeline("level2 child of level1");     base.printhierarchy();   } } 

if looking @ level2 class, can see level2.printhierarchy follows the open/closed principle because on own , calls base method overriding.

however, if @ level1 class, appears in violation of ocp because not call base.printhierarchy -- in fact, in c#, compiler forbids error "cannot call abstract base member".

the way make level1 appear follow ocp change root.printhierarchy empty virtual method, can no longer rely on compiler enforce deriving classes implement printhierarchy.

the real issue i'm having while maintaining code here seeing dozens of override methods not call base.whatever(). if base.whatever abstract, fine, if not, whatever method might candidate pulled interface rather concrete override-able method -- or class or method need refactored in other fashion, either way, indicates poor design.

short of memorizing root.printhierarchy abstract or putting comment inside level1.printhierarchy, have other options identify whether class formed level1 violating ocp?


there's been lot of discussion in comments, , answers too. having trouble figuring out ask here. think frustrating me that, as @jon hanna points out, virtual method indicates "you must implement me" whereas other times means "you must extend me -- if fail call base version, break design!" c# doesn't offer way indicate of mean, other abstract or interface "must implement" situation. (unless there's in code contracts, little out of scope here, think).

but if language did have must-implement vs. must-extend decorator, create huge problems unit-testing if couldn't disabled. there languages that? sounds rather design-by-contract, wouldn't surprised if in eiffel, instance.

the end result as @jordão says, , it's contextual; i'm going leave discussion open while before accept answers still.

root defines following: root objects have printhierarchy method. defines nothing more printhierarchy method that.

level1 has printhierarchy method. not stop having printhierarchy method has in no way violated open/closed principle.

now, more point: rename "printhierarchy" "foo". level2 follow or violate open/closed principle?

the answer haven't clue, because don't know semantics of "foo" are. therefore don't know whether base.foo should called after rest of method body, before rest, in middle of it, or not @ all.

should 1.tostring() return "system.objectsystem.valuetype1" or "1system.valuetypesystem.object" maintain pretence @ open/closed, or should assign call base.tostring() unused variable before returning "1"?

obviously none of these. should return meaningful string can. base types return meaningful string can, , extending not benefit call base.

the open/closed principle means when call foo() expect fooing happen, , expect level1 appropriate fooing when call on level1 , level2 appropriate fooing when call on level2. whether level2 fooing should involve level1 fooing happening depends on fooing is.

base tool helps in extending classes, not requirement.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -