Designing to be inherited is extra effort


I saw this rather nice explaination for why sealed is used in so many .Net classes over on as a comment to a rant about how .Net is bad for your design skills...

Designing to be inherited is extra effort
[Shane King] April 16, 2004 20:26:54 EDT

It's extra effort, since you have to think about not only what public interface to provide to users of the class, but also what interface to provide for people who want to inherit your class. Often it's just not worth putting in that effort. Marking your class as sealed is a way of saying "I didn't have the time or inclination to ensure that you can inherit this in a reasonable fashion, so I'm not going to let you do it at all". It's not telling your users what they should and shouldn't do as such, it's admitting you don't know enough to allow them to inherit, and so not letting them do so. Which is IMO a better decision than letting them do it anyway, and then getting stung when you have to change the class in a way that breaks the classes that inherit from you.

It seems like a resonable position, but personally I'd prefer it if sealed were just advisory and the user could decide to go against the designer's wishes if they wanted to try their luck...


I hate to say it, but I almost prefered the COM mechanism to .NET. There was no inheritence of public interfaces, only aggregation. In the end it turns out interface aggregation is more important than inheritence.

Yeah, I know what you mean; with COM you could always reimplement the inteface and aggregate the original object to reuse but add functionality. With .Net you get so many chances to almost be able to extend nicely but you cant. Take the sockets stuff, you could almost inherit from Socket to, say, add SSL support, and then be able to use all the TcpClient stuff with your new improved socket but due to lack of interfaces, or other restrictions, etc, you cant... Most annoying...

You really don't want to inherit from socket. What you want to do is be able to modify its behavior. I think the strategy pattern would be a better solution. It would better if the transport was customizable, that way you don't get into the "should I call the base class first or last" problem.

I have concluded that almost all problems like this can be solved with "behavioral polymorphism." Again the classic example is the strategy pattern.

I agree, that would be a better approach.

Leave a comment