Hi, is that a Liskov case ? (https://en.wikipedia.org/wiki/Liskov_substitution_principle)
Let ϕ ( x ) \phi (x) be a property provable about objects x x of type T. Then ϕ ( y ) {\displaystyle \phi (y)} should be true for objects y y of type S where S is a subtype of T.
I've an Order class that has a Product typed property.
Then I've a ExpeditorOrder class that extend this Order class and instead of using a Product property it uses an ExpeditorProduct typed property which extend Product.
The code works, like expected by Liskov definition: A principle in object-oriented programming stating that an object (such as a class) may be replaced by a sub-object (such as a class that extends the first class) without breaking the program.
But my IDE don't like it, see the code:
// $order is an 'ExpeditorOrder' object.
// getProducts() is in the 'Order' class and is type-hinted to return a collection of 'Product'
foreach ($order->getProducts() as $product) {
// 'getQty_selected()' is a method defined in 'ExpeditorProduct'
// Call to an undefined method App\Entities\Product::getQty_selected()
// Code works, but IDE don't understand it because it thinks '$product' is a 'Product' object but it's a 'ExpeditorProduct' object actually
echo $product->getQty_selected();
}
I can't find a solution to this, bad OOP design ?
The best I found is to type-hint the $products collection with /** @var ExpeditorProduct $product */ to enforce it's an ExpeditorProduct type and not Product.
Can I like, retype-hint the getProducts() in the Order child classes to change return type from Product to ChildProduct ?
Thanks for reading ! 