9

I'm not trying to say I know something everyone else doesn't but I've been solving more and more designs with the use of nested classes, so I'm curious to get a feeling for the acceptablilty of using this seemingly rarely used design mechanism.

This leads me to the question: am I going down an inherintly bad path for reasons I'll discover when they come back to bite me, or are nested classes maybe something that are underrated?

Here are two examples I just used them for: https://gist.github.com/3975581 - the first helped me keep tightly releated heirarchical things together, the second let me give access to protected members to workers...

2
  • I just want to say thanks for the answers/insights - I'm not sure how to pick an answer so I'll leave it while I mull over the advice I got and revisit... Oct 30, 2012 at 16:54
  • Also related: stackoverflow.com/q/7984529/23715
    – Alex Che
    Aug 23 at 9:50

5 Answers 5

6

I would not call this a "rarely used design mechanism" - at least, not universally: although there are shops where some contributors may frown upon using nested classes, this is not an obscure feature at all.

Although the existence of classes with assembly visibility and the introduction of lambdas has significantly reduced the need for nested classes*, they remain a valid design choice. Although there is some overlap with internal classes inside a namespace, the nested classes feature is unique in letting you hide a class entirely inside another class.


* The use of a similar feature in Java is much higher, because other alternatives available in C# are not there in Java.

2
  • So is it good to hide a class entirely in another class as per the essence of OOP design?
    – Maxood
    Sep 14, 2016 at 23:03
  • 1
    @Maxood It's good to hide a class if you can hide it. The user of your API should know as little as possible about the way your API is implemented. Sep 15, 2016 at 0:28
3

Consider for a moment that you're writing a class inside another class, that will never be used anywhere else in your program. Because if you were using it elsewhere, you'd make it an ordinary public class, just like all the others.

So the thing that is supposed to make OOP great (reusability) is absent here. Besides, what could you achieve with a nested class that you couldn't achieve with ordinary methods and private members within the parent class?

For a useful software pattern utilizing nested classes, look here.

3
  • 10
    I've never bought the reusability thing, at least not the way it's usually put. (1) Calling into existing code/classes (which you appear to talk about, and which I usually see as definition of reuse) has absolutely nothing to do with OOP, it's just basic modularity. (2) Subtype polymorphism, which is one defining characteristic of OOP, allows reuse of client code by making the specific implementation irrelevant, i.e. it works exactly the same way whether or not the concrete class is accessible or not. IOW that's reuse I buy, but it works with nested classes just as well.
    – user7043
    Oct 29, 2012 at 18:42
  • 1
    I'd say there's also the namespace insulation given by the parent class - so if you wanted, both classes A and B could have nested class "Params", and the access to non-public members of the containing class. Aren't they both reasons to have inner classes that are used outside the class? Oct 29, 2012 at 19:08
  • @AaronAnodide That should be an answer about a good way to use nested classes. It's exactly how/why I use them, it helps to organize the code.
    – Izkata
    Oct 30, 2012 at 16:25
3

am I going down an inherintly bad path

I think in your second example (the worker subclasses) you definitely are. You have mapped each subclass to a specific state in the super class. So now each time you want to add a state to the super class you will need to make a change in three locations (add state to super class, add a new sub class, and change the constructor of derived class to add sub class to list).

The use of nested classes to access private members does appear to be a valid use (I have never personally done it) but your specific case does not work here.

As for the body part example. Because all of the nested classes are public you aren't really doing much except namespacing. If these classes grow to include more functionality you may just find that the nested classes just clutter the interfaces and you are sifting through code to find something specific. I also notice that because you have nested classes you are forced to break naming conventions and name your classes with lower case (maybe this was a choice). But these arguments are more superficial than anything actually wrong.

Unless, of course, you needed to implement a disembodied arm. Then creating an arm by doing the following is confusing because there is no body/torso/side. (Also notice the confusing casing).

arm newArm = new Body.torso.side.arm("");
1
  • The need to break official naming convention may actually be a sign that you use the things no the way they were intended to be used.
    – Alex Che
    Aug 23 at 9:57
1

The only advantage I can think of nested classes is that they can be made private (or protected). I'd say in this case nested classes can help you encapsulate functionality if a class is intended to be used by the outer class and that class alone.

1

In my experience, nested classes

  • Came back to haunt me
  • Have been used when I wanted to cut corners
  • Made testing a nightmare
  • Had negative impact on separation of concerns and overall design

Had a brief look at your class, and right away I think that:

  • It's painful to look at it because the class is huge
  • I can't test "fingers" without pretty much creating entire body
  • I can't have multiple implementations of torso. Doesn't seem that obvious in a "human body" context, but in a different scenario this would become obvious.

Why not separate your class into multiple classes and give them separate namespaces. E.g.

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.