2

Not sure exactly how to phrase the question succinctly for the title.

I have a collection class that extends another collection class.

The parent collection-class has a method addMember(someClass $obj) that adds an object to the collection.

The child collection-class groups objects of the child class of someclass, someClassChild. I thought that a child class's method's signature would pass muster as long as the signature was the same or required children of the classes the parent required.

E.g. addMember(someClassChild $obj)

But I tried it and I'm getting a warning about strict standards.

So then, how to I implement a collection class as a child of another collection class to provide functionality for parent/child base objects?

1

2 Answers 2

4

It's a violation of Liskov's substitution principle. Basically any class that uses SomeClass must be able to rely on the fact that addMember accepts a SomeClass or any of its subclasses. In your example, that's no longer true, because now you have an implementation of SomeClass that will cause a fatal error whenever a SomeClass object is passed that is not a SomeClassChild.

Some languages allow contravariance of method arguments, meaning that a subclass may accept a more general type (rather than more specific like in your example), which makes sense, because any SomeClass is also a SomeSuperClass if SomeClass extends SomeSuperClass. PHP however doesn't support this.

3

The principle you're looking for is covariance and contravariance in type hints. To my knowledge, PHP doesn't support it.

1
  • 1
    I guess you're right. I was able to work around that by changing the signature to match the parent, and then adding a bit where it uses if((!$obj instanceof someClassChild) ) return false Commented Feb 23, 2015 at 8:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.