Search code examples
phpclassooptraitsmultiple-inheritance

Which is the best way of multiple inheritance in php?


I have main class, that should be extended by 3 specific class.

Main requirement is:

-For OOP I need to demonstrate code structuring in meaningful classes that extend each other, so would be an abstract class for the main product logic. An approach for this would be to have a product base class, that would hold all logic common to all products and then specific product type would extend the product base class with that type-specific stuff.

-The idea is to create an abstract class with all product common logic, like getTitle, setTitle etc. Then create child product classes for each product type to store product type specific logic like furniture sizes, CD size, book weight etc..

This task I have solved with php traits:

Main.php

class Main 
{
    use Book;
    use Disc;
    use Furniture;
    // common properties and methods
}

Disc.php

trait Disc
{
    public function setSize($size)
    {
        $this->size = $size;
    }  
}

Book.php

trait Book
{
    public function setWeight($weight)
    {
        $this->weight = $weight;
    }
}

Furniture.php

trait Furniture
{
    public function setHeight($height)
    {
        $this->height = $height;
    }
    public function setWidth($width)
    {
        $this->width = $width;
    }
    public function setLength($length)
    {
        $this->length = $length;
    }
}

I have solved this with interfaces like that:

Main.php

class Main
{
   // common properties
}

Types.php

interface Weight
{
    public function setWeight($weight);
}
interface Size
{
    public function setSize($size);
}
interface Fdim extends Weight,Size
{
    public function setHeight($height);
    public function setWidth($width);
    public function setLength($length);
}
class Furniture extends Main implements fdim
{
    public function setWeight($weight)
    {
        $this->weight = $weight;
    }
    public function setSize($size)
    {
        $this->size = $size;
    } 
    public function setHeight($height)
    {
        $this->height = $height;
    }
    public function setWidth($width)
    {
        $this->width = $width;
    }
    public function setLength($length)
    {
        $this->length = $length;
    }
}

Is this the best solution with interfaces which responds to the above requirements?

Which is more acceptable traits or interfaces? What do you recommend?

I have a question: Is there a better solution to this task with requirement above? I have tried abstract classes and interfaces as well, but in my opinion the requirements are more satisfied with traits. What do you recommend?


Solution

  • As I have written in comment, I would suggest something like this:

    abstract class Product
    {
        // Get/Set title, SKU, properties which are common for *all* products
    }
    

    Then some interfaces:

    interface HavingWeight
    {
        // Get/Set weight
    }
    

    Traits:

    trait WithWeigth
    {
        // Get/Set weight implementation
    }
    

    Then concrete class of Book:

    class Book extends Product implements HavingWeight
    {
       use WithWeight;
    }
    

    Using interfaces have the very important advantage, that use can then use code like following:

    if($product instanceof HavingWeight)
    {
        // Show weight
    }