ID: 41461
Comment by: php at whoah dot net
Reported By: ralph at smashlabs dot com
Status: Verified
Bug Type: Class/Object related
Operating System: *
PHP Version: 5.*, 6CVS (2009-04-25)
New Comment:
Should this not be possible without errors or notices? I am
overloading an overridden method. If memory serves me, I am able to do
this in other OO languages (Java, .NET/C#).
class BaseClass {
public function TestFunction ($parameter) {
var_dump($parameter);
}
}
class FooClass extends BaseClass {
public function TestFunction () {
parent::TestFunction('This is Foo');
}
}
class BarClass extends BaseClass {
public function TestFunction () {
parent::TestFunction('This is Bar');
}
}
$test = new FooClass();
$test->TestFunction();
$test = new BarClass();
$test->TestFunction();
Instead:
Strict Standards: Declaration of FooClass::TestFunction() should be
compatible with that of BaseClass::TestFunction()
Strict Standards: Declaration of BarClass::TestFunction() should be
compatible with that of BaseClass::TestFunction()
Previous Comments:
------------------------------------------------------------------------
[2008-08-08 19:57:45] [email protected]
I took a look into it, here's some findings:
1. There's no difference between how arguments are matched with and
without interface. The difference is that with no interface binding
would happen in this case in compile time, so if your error reporting
did not have E_STRICT by default, error_reporting(E_ALL | E_STRICT) is
not executed and so the error is not seen.
2. someFunc($uno, $dos, $tres) is not a good replacement for
someFunc($uno, $dos) even ignoring the by-ref return, since it has extra
required argument. Making it not required should pass the strict check.
3. I think it can be allowed to override function that returns by-val
with function that returns by-ref, but not vice versa.
------------------------------------------------------------------------
[2007-06-19 21:52:26] ralph at smashlabs dot com
Marcus,
After re-reading, I didn't think that I was clear in my original bug
report, so I attempted to clarify the matter (2 posts up). I still
think this is a problem and that it hinders the usage of interfaces as
it restricts concrete classes from overriding methods introduced at the
abstract layer, not the interface layer.
If this is still by design, go ahead and close, but I wanted to make
absolutely sure as most people either do not care about E_STRICT, or
haven't run into the problem yet ;)
Thanks again,
Ralph
------------------------------------------------------------------------
[2007-05-28 17:53:41] ralph at smashlabs dot com
PS. I did check this with the internals list before I posted.. And I
think you actually confirmed it for me on the list
http://news.php.net/php.internals/29646
Thank you for your time,
-ralph
------------------------------------------------------------------------
[2007-05-28 17:42:50] ralph at smashlabs dot com
I am sorry, perhaps I should rephrase (I was rushed when I wrote the
original bug report) and I don't think I was especially clear.
In general, we are speaking strictly of Method Overriding. PHP
currently allows concrete classes to override methods in abstract
classes as demonstrated by this code:
webdevelo...@webdevelopment ~/tmp $ cat test_method_override.php
<?php
error_reporting(E_ALL | E_STRICT);
class Z_Abstract
{
public function someFunc($one, $two)
{ }
}
class Z_Concrete extends Z_Abstract
{
public function & someFunc($uno, $dos, $tres)
{ }
}
$o = new Z_Concrete();
webdevelo...@webdevelopment ~/tmp $ php test_method_override.php
webdevelo...@webdevelopment ~/tmp $
As you can see, no E_STRICT was triggered, thus allowing the concrete
class to override the method from the abstract class.
On the other hand, when adding an _empty_ interface to the superclass
hierarchy, the behavior changes. The simple inclusion of an interface
now (albeit empty) seemingly shouldn't add any complexities to method
overriding for methods outside the scope of the interface itself. I
have done a bit more homework, and it seems like not alot of IS_A
inheritance literature exists to describe this problem, let alone
justify the behavior we are seeing in practice.. See code:
webdevelo...@webdevelopment ~/tmp $ cat test_method_override2.php
<?php
error_reporting(E_ALL | E_STRICT);
interface Z_Interface
{ }
class Z_Abstract implements Z_Interface
{
public function someFunc($one, $two)
{ }
}
class Z_Concrete extends Z_Abstract
{
public function & someFunc($uno, $dos, $tres)
{ }
}
$o = new Z_Concrete();
webdevelo...@webdevelopment ~/tmp $ php test_method_override2.php
Strict standards: Declaration of Z_Concrete::someFunc() should be
compatible with that of Z_Abstract::someFunc() in
/home/webdeveloper/tmp/test_method_override2.php on line 14
At the very least, I looks like one of the two is broken (At least in
the spirit of OOP as it relates to polymorphism and overriding methods.)
------------------------------------------------------------------------
[2007-05-28 15:08:50] [email protected]
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php
PHP follows strict is_a inheritance.
By the way, it is called signature and even if you could change it it
would not solve the problem. And anyway it would break inheritance
rules.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/41461
--
Edit this bug report at http://bugs.php.net/?id=41461&edit=1