Web lists-archives.com

[PHP] How do I handle covariant parameters and not fall foul of LSP.




Hi.

I have an abstract base repo and an abstract base entity. Both provide
functionality
appropriate to all repos/entities.

I extend these to allow a specific repo to handle a specific entity.
But I can't
declare the specific entity type hint in the specific repo as it is in
conflict.

I'm hitting my head against LSP, but wanting
https://en.wikipedia.org/wiki/Covariance_and_contravariance_
(computer_science)#Contravariant_method_argument_type

<?php

abstract class BaseEntity{}

abstract class BaseRepo
{
   public function processEntity(BaseEntity $entity){}
}

class Person extends BaseEntity{}

class PersonRepo extends BaseRepo
{
    public function processEntity(Person $entity)
    {
        parent::processEntity($entity);
    }
}

$person = new Person;
$personRepo = new PersonRepo;
$personRepo->processEntity($person);


Warning: Declaration of PersonRepo::processEntity(Person $entity)
should be compatible
with BaseRepo::processEntity(BaseEntity $entity)

I know some people 'get' this. But for me, it really seems to make next to no
sense at all.

I have some base behaviour for all entities. I have a base repo that can work
with that base entity, regardless of how that entity is extended.

If the base type were not abstract, then I can see that I wouldn't substitute
anything logically, but I'm using abstract base types. And if set theory is
to be believed, then if B extends A, B is still an A. And so, where I can
receive an A, I can receive a B.

Obviously, I'm missing / lacking an understanding of LSP as it relates to my
code.

I'm happy to read more, but I'd appreciate some recommendations on what to
read.

Of course, if anyone can 'correct' my code such that a concrete repo works on
concrete entities, but also allows for the base behaviour, then I'd be very
grateful.

Regards,

Richard.