Bug #70270 [Opn->Csd]: Interface ignores precedence order of traits
| From: | krakjoe@php.net | Date: | Sun, 27 Mar 2016 06:28:03 +0000 |
| Subject: | Bug #70270 [Opn->Csd]: Interface ignores precedence order of traits | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-200144@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=70270&edit=1
ID: 70270
Updated by: krakjoe@php.net
Reported by: soevilcat at mail dot ru
Summary: Interface ignores precedence order of traits
-Status: Open
+Status: Closed
Type: Bug
Package: Class/Object related
PHP Version: 7.0.0beta3
-Assigned To:
+Assigned To: krakjoe
Block user comment: N
Private report: N
New Comment:
This was fixed with #71414, no longer reproducible.
Previous Comments:
------------------------------------------------------------------------
[2015-08-14 11:57:58] soevilcat at mail dot ru
Description:
------------
According to docs, trait's methods take precedence over inherited methods. However, interfaces
seem to ignore trait's methods if the class has a parent...
The script below has some marked parts: A - extending from a parent class; B - applying a trait; C -
local function member. All three points supply a method named "get_value". The order of
precedence between them is C, B, A: local member; if absent, then trait's member; if absent,
then parent's member. The Interface requires get_value() method with a specific signature
provided by either part B or C. The parent class has a different signature, though only by optional
arguments.
The script compiles with parts A, B and C left in. However, if you delete part C (current class
members; that means that trait's member does take precedence, and you can easily confirm that
instantiating an object and calling the method), it gives off fatal error:
Fatal error: Declaration of Value::get_value() must be compatible with ValueHost::get_value($code =
NULL)
If you delete parts C and A, leaving only trait's member (no parent class), then there's
no fatal error. The interface takes precedence of parent's method over trait's method
while the composition doesn't!
In the script below, part C is commented for demonstration purposes.
Test script:
---------------
interface ValueHost { public function get_value($code=null); }
trait Value_has_registers {
public function get_value($code=null) {
if ($code===null) return parent::get_value(); else return $this->regs[$code];
}
}
abstract class Value {
protected $content;
public function get_value() { return $this->content; }
}
class Value_entity /* (A) */ extends Value /* (A) ends */ implements ValueHost
{
/* (B) */ use Value_has_registers; /* (B) ends */
/* (C)
public function get_value($code=null) {
if ($code===null) return parent::get_value(); else return $this->regs[$code];
}
(C) ends */
}
Expected result:
----------------
no errors
Actual result:
--------------
Fatal error: Declaration of Value::get_value() must be compatible with ValueHost::get_value($code =
NULL)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70270&edit=1