1

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?

Community
  • 1
  • 1
Daniel Katz
  • 2,271
  • 3
  • 25
  • 27
  • *I assume there is basically only one way of accomplishing this by using private nested classes*. That's incorrect. Read : [Composition](https://en.wikipedia.org/wiki/Object_composition). It's called *Object composition* for a reason. – Chetan Kinger Feb 26 '17 at 07:44
  • Why do we *need* nested classes? We survive just fine without them-it's organizational. Some languages support additional encapsulation with nested classes, but that's an implementation detail. It doesn't define a "proper" or "improper" OOPL. – Dave Newton Mar 06 '17 at 18:39

2 Answers2

4

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.

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • IMO the Car&Wheel example is aggregation,Composition would be some TransparentMaterial class and a property like refraction index.Many real world examples of "components" can continue to exist after the destruction of the bigger component (which was assigned the abstract concept of being a Car,Forest,Network..)How many parts can you destroy until you won't be able to tell it's a car?A refraction index for a TransparentMaterial will definitely not exist without the instance of TransparentMaterial:"B has no meaning or purpose in the system without A..and cannot be transferred to another object". – Daniel Katz Feb 26 '17 at 11:00
  • If you create a wheel and assign it later to a car then it obviously can be transfered/assigned to any other car, which is not a composition, is it? – Daniel Katz Feb 26 '17 at 11:05
  • @DanielKatz Check that I've said that "practically all systems use aggregation".... BTW in terms of how a car works, my example is composition because all car components are useless if they're not assembled to a car. – Matías Fidemraizer Feb 26 '17 at 11:18
  • @DanielKatz Anyway, is your question about composition vs. aggregation, or about the role of nested classes? :\ – Matías Fidemraizer Feb 26 '17 at 11:19
  • My question is about finding a common ground because I feel like whatever people say doesn't make any sense to me. – Daniel Katz Feb 26 '17 at 11:23
  • @DanielKatz You won't find the God of Software Definitions on which you can blindly rely on.... Your question is about the role of nested classes and composition, right? If you're looking for composition vs aggregation vs association... There's already a Q&A... :( – Matías Fidemraizer Feb 26 '17 at 11:25
  • @DanielKatz I'm going to edit my answer so we throw away the part of comparing different kinds of OOP composition. – Matías Fidemraizer Feb 26 '17 at 11:27
  • I like the example of bank accounts being a composition.The building may be destroyed but this is not what the bank is based on. Lets say a bank is a piece of software that takes care of creation&destruction of bank accounts. Unlike a forest-you can theoretically replant a tree to a different forest. But as soon as the bank software cease to exist the bank accounts must disappear as well. But this is very interesting, I wouldn't personally want to use a nested class (as it should be for a composition) because I would end up having an enormous single class. – Daniel Katz Feb 26 '17 at 11:34
  • 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. – Daniel Katz Feb 26 '17 at 11:34
  • @DanielKatz Nested classes != Partial classes. See my updated answer, you're going too far and you focus on types of aggregation. But this has nothing to do with your question and the topic. – Matías Fidemraizer Feb 26 '17 at 11:37
  • @DanielKatz Take your time, think about what I've already tried to explain you, look for more info on Google, and I'm pretty sure you'll be able to solve your concern. As I see you now, it seems like no answer will be able to address your main issue: it's you how need to convince yourself about a given knowledge. There's nothing definitive if you don't rely on others knowledge. – Matías Fidemraizer Feb 26 '17 at 11:47
  • Well I happen to know JavaScript so I'd post my own answer with my own example and see how that will work out. I'll up-vote your answer anyway. I hope that's ok. – Daniel Katz Mar 02 '17 at 02:06
  • @DanielKatz But yours isn't an answer but more background about your own question... Sorry but I don't know what you want to get convinced that nested classes have nothing do with composition......... :( – Matías Fidemraizer Mar 02 '17 at 03:35
  • @DanielKatz StackOverflow is not a forum. It's about concrete questions and answers. We could end up converting this into a doctoral thesis: D Current state of OOP says that nested classes have nothing to do with composition. This is a fact and don't waste your time theorizing unless you want to compose a book about a new point of view of OOP. And please understand that my words are kindy. I love discussing about such things, but this isn't a good site to do so. – Matías Fidemraizer Mar 02 '17 at 18:53
0

In wikipedia, there's also the following example of composition without using private nested classes.

class University
{
  std::vector<Department> faculty; //this is composition
  std::vector<People*> people; //this is aggregation

  University()  // constructor
  {
    // Composition: Departments exist as long as the University exists
    faculty.push_back(Department("chemistry"));
    faculty.push_back(Department("physics"));
    faculty.push_back(Department("arts"));
  }
};

For a true composition we don't have to make the whole class private as long as we treat instances of departments appropriately, i.e. we need to make sure that all departments will actually get deleted when the university ceases to exist.

An analogous ways of implementing different compositions in JavaScript would be as follows:

/*this is a component's "class"*/
function Text(txt){
   this.txt = txt;
}

/*this is a composite's "class"*/
function Hello(begining){
   /*public object*/
   this.begining = begining;

   /*this is like making an instance from a nested function which is a composite*/
   var Middle = new (function Middle(txt){
       this.txt = txt;
   })(" - ");

   /*private object - also a composite, even though it's made of the public class Text*/
   var Ending = new Text("that's all.");

   /*The use of the private property Ending*/
   this.Say = function(){
      var msg = this.begining.txt + Middle.txt + Ending.txt;
      console.log(msg);
   }
}
/*
   This txt variable will be the "begining" text. It could still be a composite, but
   only if it's not used in another composite when purpose is to be 
   "an untransferable part" and not a "visitor".
*/
var txt = new Text("Dan");
var say1 = new Hello(txt);
var say2 = new Hello(new Text("To be or not to be"));

say1.Say()  /*Dan - that's all.*/
say2.Say() /*To be or not to be - that's all.*/

But even the transferability is often a neglected rule when people see "cars" having "wheels" as parts (rather then "visitors")

Instead of perhaps "neural network" and "neurons" or "forest" and "trees". Trees don't get replanted to a different forest so often.

And since the wheels can still be understood as parts of a composite, it doesn't have to differ from aggregation in code.

Daniel Katz
  • 2,271
  • 3
  • 25
  • 27