Method Overriding and Strict Standards

跟風遠走 提交于 2019-12-10 14:28:54

问题


So I have this parent class:

class GenericHTMLElement
{
    public function addElement(GenericHTMLElement $element) {}
}

that is extended by these two classes

class ListViewItem extends GenericHTMLElement
{

}


class ListView extends GenericHTMLElement
{
    /**
     * @param ListViewItem $element
     * @throws WrongTypeException
     */
    public function addElement(GenericHTMLElement $element)
    {
        if (!$element instanceof ListViewItem)
        {
             throw new WrongTypeException("ListViewItem", $element);
        }
        parent::addElement($element);
    }
}

This works great. The problem is that it is not very clear that ListView::addElement() only accepts a ListViewItem object as argument.

Moreover, when generating documentation, it assumes $element should be of type GenericHTMLElement even with that javadoc comment.

However, changing the typehint triggers the StrictStandards warning.


EDIT: changed the questions a bit...

Q. Why is changing parameters in method overriding a violation of Strict Standards? You can do that in other programming languages. And in PHP, you can do that in the constructor

Q. What are the implications of violating the Strict Standards in this case? As I understand it, the strict warning appears to warn the programmer that there's a possibility someone could read the signature of the parent class and assume it's children behaves the same way. That could lead to a runtime error and halt in execution. But that is precisely what I'm trying to achieve.


EDIT:

Since it was asked in the comments, more details about this...

This is part of a Template Engine from Mobile Web Applications that uses JQuery Mobile at its core.

JQuery mobile has specific requirements regarding how to structure a "page". jQueryMobile also uses specific attributes such as data-theme or data-position.

In order to manipulate the DOM of a page, you have to enforce that structure.

GenericHTMLElement represents a "generic" block of HTML (a div, a table, etc...). A ListView is the jQueryMobile equivalent of a ul or ol. A ListView can only have a ListViewItem (li) as children. A listView, for instance, has a property named data-filter that enables or disables a search filter.

more info at http://jquerymobile.com/test/docs/api/data-attributes.html


回答1:


You already have defined the concrete type that the addElement method has to accept.

If you now extend from that type and create a subtype that is more specific - or better said: different - , you are breaking that contract.

PHP warns you about that with the strict standards warning.

Either the listview element is generic and then it has to accept anything generic, too. Or it is something different but then it can not be generic in it's own interface.

So you should not disable the strict warning but think twice what you do there.

It looks like that you want to be in conformance with the HTML DTD here that only allows certain elements within others. For example it is not allowed to place a <a> tag inside an <a> tag. However I find it highly non-productive if you try to break that down onto individual types and subtypes. You won't finish your model - if even it can be properly expressed with PHP. However you should discuss that with your own first.

Maybe the standard DOMDocument sheds some light on how HTML can be represented.



来源:https://stackoverflow.com/questions/13220489/method-overriding-and-strict-standards

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!