Private Nested Classes - Are They Necessary for Composition?

advertisements

This is my naive thought process. I appreciate when anyone points out any discrepancies.

I know that in Java it is possible to create private nested classes. But in PHP (calling itself an "OOL") no such thing is easily possible.

However, there may be an instance where I need to use a helper class within only one other class.

This naturally led me to consider using composition about which I think its supposed to actually solve this kind of a problem, for the following reason:

Wikipedia:

  • It is only called composite, if the objects it refers to are really its parts, i.e. have no independent existence.
  • Aggregation differs from ordinary composition in that it does not imply ownership. In composition, when the owning object is destroyed, so are the contained objects. In aggregation, this is not necessarily true.

So since in composition the components aren't supposed to exist without the other composite object, I assume there is basically only one way of accomplishing this by using private nested classes, otherwise I will need to have the Component class visible, making it instantiable also somewhere else, violating the creation/destruction-of-components-within-the-composite-class rule.

Now I came across PHP where it is not possible at all to create nested classes (or maybe with some magic) which may lead to a question why do we need nested classes at all?

Compelling reasons for using nested classes include the following:

  • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

  • It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

  • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.

So in my opinion, as nested classes increase encapsulation (and thus allowing for implementation of a composite concept) it should be always possible to create a nested class in a proper OOL.

I also looked up the definition of an OOP and it only mentions the support for Encapsulation, Abstraction, Inheritance, Polymorphism concepts.

OOP

Encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition.

Abstraction is the development of classes, objects, types in terms of their interfaces and functionality, instead of their implementation details. (e.g. instead or creating a single sequence of commands to work with a radius and points we would abstract a concept of a circle. So we define a class Circle and a its attributes/functions in such a way that it reflects this abstract concept.)

Inheritance is supposed to be the is-a relationship between abstractions (allowing for code reuse).

Polymorphism allows for overriding and overloading methods.

A guy asked a question here which actually complies exactly with my understanding of the problem and IMHO received quite inaccurate answer, being told to be really confused and being provided with a code sample which IMO is not a proper composition, as it is not really possible in PHP. In addition someone may argue that composition isn't about inner classes.

So am I understanding something really wrong?


Those concepts like composition are generic and their implementation may vary depending on the programming language.

In the other hand, I wouldn't say that the definition of composition which includes [...] have no independent existence refers to being able to create instances or not from different scopes.

No independent existence is a more conceptual than practical rule. It means that a wheel can never be the composition root because the root is the car. That is, a wheel can't exist independently of a car.

Therefore, the conclusion is nested classes are just an implementation detail and they have nothing to do with composition. Note that objects aren't created from classes in all programming languages but composition and many other features are still possible. Would you say that object composition isn't possible in JavaScript?

var car = { manufacturer: "Ford", model: "Focus" };
// I can create the wheel after the car
var wheel = { color: "black" };
// but it'll be always tied to some car
car.wheel = wheel;

Anyway, practically all systems implement aggregation, which is a flavor of composition. Take a look at this Q&A at Software Engineering.

While a wheel is useless without being part of a car, wheels are still sold apart as one of the many mechanical pieces of which a car is built, hence a wheel can live alone yet it's useless as just a piece.

Generic definition of composition in OOP

The OP is too concerned and focused on the formal definition of composition in terms of UML: composition, association, direct association, aggregation...

BTW, the term composition in OOP has a more simple meaning which is often used, for example, when discussing when to use inheritance or when to avoid it, we talk about composition over inheritance. See for example this Q&A from 2010: What is composition as it relates to object oriented design? on which basically all answerers have a consensus about the definition of composition.

At the end of the day, the term composition is the approach to create an object graph: simple types are associated together to create more complex types.

Thus, as I've already explained in the first part of this answer, nested classes are just a programming language implementation detail and they're not crucial to implement any flavor of composition.

OP said on some comment:

But conceptually in order to implement it properly as a composition, I'd prefer something like partial classes (as in C#) allowing me to separate code into multiple files but restricting the instantiability to the main class only. I know you don't agree with me, I have to express my view somehow.

This is a wrong example because partial classes are just a syntactic sugar to glue multiple files defining the same class and later everything is the same class.

C# has nested classes:

public class A
{
     public class B
     {
     }
}

But you need to understand that type definitions have nothing to do with objects from a conceptual point of view because an object-oriented language may or may not have a type system and classes, but yet it can support composition and all its flavors.