覆盖函数不兼容

Nan*_*nne 6 php overriding arrayobject

TL; DR

我想重写offsetSet($index,$value)ArrayObject这样的:offsetSet($index, MyClass $value)但它会产生一个致命错误("声明必须是兼容").

什么为什么

我正在尝试创建一个ArrayObject子类,强制所有值都是某个对象.我的计划是通过覆盖所有添加值并为其提供类型提示的函数来执行此操作,因此您无法添加除值之外的任何内容.MyClass

怎么样

第一站:append($value);
来自SPL:

/**
 * Appends the value
 * @link http://www.php.net/manual/en/arrayobject.append.php
 * @param value mixed <p>
 * The value being appended.
 * </p>
 * @return void 
 */
public function append ($value) {}
Run Code Online (Sandbox Code Playgroud)

我的版本:

/**
 * @param MyClass $value
 */
public function append(Myclass $value){
    parent::append($value);
}
Run Code Online (Sandbox Code Playgroud)

似乎像魅力一样工作.

你可以在这里找到这个工作的例子

第二站: offsetSet($index,$value);

再次,从SPL:

/**
 * Sets the value at the specified index to newval
 * @link http://www.php.net/manual/en/arrayobject.offsetset.php
 * @param index mixed <p>
 * The index being set.
 * </p>
 * @param newval mixed <p>
 * The new value for the index.
 * </p>
 * @return void 
 */
public function offsetSet ($index, $newval) {}
Run Code Online (Sandbox Code Playgroud)

我的版本:

/**
 * @param mixed $index
 * @param Myclass $newval
 */
public function offsetSet ($index, Myclass $newval){
    parent::offsetSet($index, $newval);
}
Run Code Online (Sandbox Code Playgroud)

但是,这会产生以下致命错误:

致命错误:Namespace\MyArrayObject :: offsetSet()的声明必须与ArrayAccess :: offsetSet()的声明兼容

你可以在这里看到这个版本的工作原理

如果我这样定义它,它很好:

public function offsetSet ($index, $newval){
    parent::offsetSet($index, $newval);
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看此版本

问题

  1. 为什么不用offsetSet()上面的代码覆盖工作,但是append()呢?
  2. 我有一切,如果我添加的定义添加对象的功能exchangeArray()旁边那些append()offsetSet()

Vol*_*erK 3

abstract public void offsetSet ( mixed $offset , mixed $value )
Run Code Online (Sandbox Code Playgroud)

由ArrayAccess接口声明,但public void append ( mixed $value )没有相应的接口。显然,在后一种情况下,php 比接口更“宽容”/宽松/无论如何。

例如

<?php
class A {
    public function foo($x) { }
}

class B extends A {
    public function foo(array $x) { }
}
Run Code Online (Sandbox Code Playgroud)

“only”打印警告

Strict Standards: Declaration of B::foo() should be compatible with A::foo($x)
Run Code Online (Sandbox Code Playgroud)

尽管

<?php
interface A {
    public function foo($x);
}

class B implements A {
    public function foo(array $x) { }
}
Run Code Online (Sandbox Code Playgroud)

保释

Fatal error: Declaration of B::foo() must be compatible with A::foo($x)
Run Code Online (Sandbox Code Playgroud)