sneakyimp wrote:Man I don't know why you might be doing that
In languages that are more statically typed, it can avoid unnecessary casts. For example, consider this C++ class hierarchy:
class X
{
public:
// C++ quirk: destructors for polymorphic base classes are usually declared
// virtual to avoid undefined behaviour on delete of a derived
// class object via a base class pointer
virtual ~X() {}
// A virtual clone function to mimic a virtual copy constructor:
virtual X* clone() const
{
// Return a pointer to the cloned object:
return new X(*this);
}
};
// Y is a subclass of X
class Y : public X
{
public:
virtual X* clone() const
{
// Safe upcast from pointer to Y to pointer to X:
return new Y(*this);
}
};
If you had an object of class Y and wanted to clone it, having a pointer to Y point to the cloned object, it would be necessary to downcast:
Y y;
Y* p = dynamic_cast<Y*>(y.clone());
whereas if you make use of covariant return types:
class Y : public X
{
public:
virtual Y* clone() const
{
return new Y(*this);
}
};
You don't:
Y* p = y.clone();
Of course, in this example Y's copy constructor is still part of the public interface so one could invoke it directly, but such an alternative is not always readily available, so in general the notion of covariant return types in such languages is useful.
That said, Derokorian's example is news to me: because of the C++ (and Java) experience I picked up after learning PHP, I expected overriding to apply to non-static methods only, i.e., if you define a static method of the same name in a subclass, it would be overloading that hides the base class' version rather than overriding. If so, then the lack of covariant return types would not matter. However, the error message demonstrates that it is an override instead, hence the return type must match (or be covariant in some future version of PHP).