I have Product classes for Products A through Z.  And each Product class has its own set of product-specific subclasses, which I'd say are tightly coupled to them, like so:

<!-- language: php -->

    //specific product class inherits from generic product
    class ProductA extends Product
    {
        function __construct()
        {
            parent::__construct();

            //product-specific subclasses that are tightly coupled to the product
            //note that they are not DI-ed, although they *could be*
            $this->weight = new WeightA();
            $this->spec = new SpecA();
        }
    }

    class Product
    {
        public $weight;
        public $spec;
        
        function __construct()
        {
            //these are generic versions in case someone calls a generic product class   
            $this->weight = new Weight();
            $this->spec = new Spec();
        }    
    }

    //example instantiation
    $p = new ProductA();
    $p->weight->a_specific = 4;

**Question:**

I spent a bit of time reflecting on whether I wanted to pass my `Weight` and `Spec` subclasses using Dependency-Injection techniques, like so (adjusting my classes respectively):

    $p = new ProductA(new WeightA(), new SpecA());

But so far I have found no good reason to do so.  In fact, doing so may increase the chance of error where I can by accident do something like this:  

    $p = new ProductA(new WeightB(), new SpecC()); //note the disparate classes

Question:  

 * Are there any good reason to DI tightly-coupled subclasses into generic class containers anyway?
 * is there a common name for this issue (pattern) that I am dealing with?
 * are there other (better) patterns available to use in my instance?

**Background:**

I am refactoring a large ball-of-mud application and it is getting some shape, but one of the patterns I have identified is that there are product-specific classes that contain a lot of product-specific sub-classes, such as in the above example.

**Possible Middle-Ground:**

Note:  alternatively if I really want to DI, I can use DI inside product-specific subclasses, like so:

    class ProductA extends Product
    {
        function __construct()
        {
            parent::__construct(new WeightA(), new SpecA());
        }
    }

    class Product
    {
        function __construct($weight, $spec)
        {
            $this->weight = $weight;
            $this->spec = $spec;
        }    
    }

I wonder if that will be a better option overall.