PHP already has horizontal inheritance. They're called traits.

How is this an improvement in anyway?

On Sat, Mar 11, 2017 at 1:36 AM, Michael Vostrikov <
michael.vostri...@gmail.com> wrote:

> Hello. I have an idea which seems rather useful. I would like to know your
> opinion,
>
> Let's say we have class Rectangle and need to have class Square which will
> be used in some operations. We don't need any rectangle, this must be only
> square.
> What if we could describe a type which is the same as another type but have
> some restrictions for properties?
>
> Something like this:
>
> class Rectangle
> {
>     private $x;
>     private $y;
>     private $width;
>     private $height;
>
>     public function __construct($x, $y, $width, $height)
>     {
>         $this->x = $x;
>         $this->y = $y;
>         $this->width = $width;
>         $this->height = $height;
>     }
> }
>
> class Square variant of Rectangle
> {
>     public function __match()
>     {
>         if ($this->width != $this->height) {
>             return ['width' => 'Width and height have to be the same'];
>         }
>
>         return true;
>     }
> }
>
> function drawSquare(Square $square)
> {
>     // ...
> }
>
> $rectangle = new Rectagle(0, 0, 10, 10);
> drawSquare($rectangle);
>
> When drawSquare() is called, the check 'instanceof' is performed. It calls
> magic method __match().
> If __match() does not return true, it throws an exception with the data
> returned:
> 'Order does not match OrderForCheckout. Reason: ...'.
>
>
> Technically, we don't have method __match() in $rectangle object. So it can
> be static, or a proxy object can be created here.
>
> The second variant can be extended.
> We may not to inherit implementation of methods, and describe another
> interface instead, for example new object can be read only.
>
> class Square variant of Rectangle
> {
>     public function ___match()
>     {
>         // ...
>     }
>
>     public function getWidth()
>     {
>         return parent::getWidth();
>     }
> }
>
> With some changes in syntax it can be defined in this way:
>
> class Square variant of Rectangle
> {
>     ...
>
>     getWidth: base::getWidth;
> }
>
>
> This is like inheritance, but semantically differs a little.
> Inheritance has vertical direction, type variants have horisontal one.
> Also type variants have an access for all methods and properties of base
> class, even for private.
>
>
> Another example. Let's say we have an order checkout process which is
> splitted into 3 steps - cart for products, date page, delivery address
> page.
> This is not an input validation, this is a validation in business logic.
>
> class Order
> {
>     public $products;
>     public $date;
>     public $address;
> }
>
> class OrderForCheckout variant of Order
> {
>     public function __match()
>     {
>         $errors = [];
>         if (empty($this->products)) {
>             $errors['products'] = 'Product list is empty';
>         }
>         if ($this->date === null) {
>             $errors['date'] = 'Date is not selected';
>         }
>         if (empty($this->products)) {
>             $errors['address'] = 'Address is not selected';
>         }
>
>         return (empty($errors) ? true : $errors);
>     }
> }
>
> public function checkout(OrderForCheckout $order)
> {
>     ...
> }
>
> $order = findCurrentOrder();
> checkout($order);  // if $order does not match requirements, the exception
> will be thrown
>

Reply via email to