views:

100

answers:

6

I'm a newbie to C#. I tried C++ and but found it too convoluted.

Here's my question. If I use inheritance, and later realize that a subclass needs a method or field that is not applicable to the other parts, should I declare that in the base class and not have it implemented in the child classes, or should I declare that method or property in the subclass?

If I choose to declare the method in the subclass, then I can no longer treat everything polymorphically. On the other hand, if I choose to put it in the base class then I end up with a lot of classes not implementing the property or method. I have seen examples in the .net framework where the 'not implemented' approach is chosen. What is the best way to go?

A: 

is it a specialized method at only one subbclass needs? then implement in the sub class. Otherwise implement as a virtual in the base class that throws a NotImplementedException. Then in any class that needs it add as override.

Preet Sangha
my thinking is that polymorphism far outweighs a bunch of not implemented methods. I just wanna get a feel for what the community thinks
CodingJoy
+1  A: 

If only one subclass has method X, of course you can't call X polymorphically, by definition. Is it reasonable for X to exist in the superclass (and therefore everywhere) but be a no-op in most cases? Sometimes it is, sometimes you just have to rethink your whole class hierarchy, i.e., why do you want to call X polymorphically, even where it might not exist (or at best be a no-op)? It's impossible to respond without knowing much, much more about your specific use case!

Alex Martelli
after you build an application, somewhere down the road you get new requirements(CHANGE is constant) and now you have to worry about changing your WHOLE architecture. situations like these have caused projects to COLLAPSE.
CodingJoy
@CodingJoy, I've never seen projects collapse for using "too little inheritance", though I've seen the opposite: inheritance is very close coupling (that's why Gof4 say "prefer composition over inheritance"). A language with polymorphism (via signatures or interfaces only), but without inheritance of implementation, while possibly requiring more boilerplatey explicit delegation via composition (which I guess might be obviated by language specific mechanisms), would be an interesting playground...
Alex Martelli
@CodingJoy - it is often >>better<< in the long run to change the class hierarchy / architecture. IMO, collapse is more likely to be caused by failing to recognize early enough that an architecture is no longer correct.
Stephen C
A: 

If it will only be used in the subclass and doesn't need to be called polymorphically, then implement it only in the subclass. However, if you need to use it polymorphically then think about what that function would mean for other subclasses of the super class.

If there is no good meaning for that function, then you may need to rethink your class hierarchy. However, you can just do No-op or throw a NotImplementedException for subclasses where the function has no valid meaning. I'm not really a fan of either, but sometimes there isn't a way around using those.

Polaris878
one of the selling point of OO is polymorphism. if i have a foreach loop on some class called Accounts and it is supposed to print out some report than it should print out ALL ACCOUNTS whether they be savings, checking, money market, stock market etc....
CodingJoy
Right... but you want to make sure the method you are calling on all accounts makes sense for each account type. In your example, not every type of account could have a maturity date etc... so you probably wouldn't want a polymorphic function for maturity date.
Polaris878
+1  A: 
Matt Brunell
If so, the native .NET Stream subclasses violate this principle. Many Streams do not support the seek() method and end up throwing a NotSupportedException. While I agree that Liskov Substitutions Principle is an important concept to live by, necessary violations may abound.I would err on the side of redesign when thinking of violating it, however, if it is expected that a subclass may not fully implement its super, then perhaps consistency in partial-implementation is appropriate (ie. where creating a subclass of a Stream).
Wayne Hartman
Well stated. I agree 100%
Matt Brunell
A: 

I've always preferred to use NotImplemented style exceptions for code that isn't finished yet. I would never personally use it just so I could push more methods into a base class.

Jay P.
A: 

For this one you need to answer some questions about the intent of your API.

  1. How is your API to be used: If your API consumers are to almost always refer to your base class, then it may make sense to put it into the base class.
  2. If the method your trying to implement is applicable to almost all derived classes that could choose to implement the functionality, then put it in the base class.

Consider System.IO.Stream, this is an abstract class with abstract methods for seek operations, it makes sense to not have to derive from something like System.IO.SeekableStrem just to get seek functionality, users of the API should only refer to Stream.

Brett Ryan