4

次のようなコードを記述すると、PHP の警告「厳格な標準: x の宣言は y と互換性がある必要があります」が表示されます。

class A {
  function foo($x) {
    ..
  }
}
class B extends A {
  function foo() {
    ..
  }
}

これは理にかなっています。なぜなら、$aであると考えられる" " のようなオブジェクト参照Aが、実行時に であることが判明する可能性があるBためです。$a->foo(3)B::foo()

私の質問は、動的にディスパッチされない静的メソッドに同じ警告が適用されるのはなぜですか?

class X {
  static function bar($x) {
    ..
  }
}
class Y extends X {
  static function bar() {
    ..
  }
}

この例では、関数Y::bar()は をオーバーライドしX::bar()ないため、警告をトリガーする理由はありませんが、PHP は引き続き警告をトリガーします。なんで?

4

3 に答える 3

2

Java とは異なり、インスタンスで静的メソッドを呼び出すことができ、それらはそのオブジェクトのランタイム タイプによってディスパッチされます。Y::bar()実際にはオーバーライドもX::bar()あり、互換性があるはずです。

<?php

class X {
  static function bar($x) {
    echo "X::bar() with x = $x\n";
  }
}
class Y extends X {
  static function bar() {
    echo "Y::bar()\n";
  }
}

echo "Static dispatch:\n";
X::bar(1);
Y::bar();

echo "Dynamic dispatch of a static method (surprise!):\n";
$arr = array(new X(), new Y());
foreach ($arr as $a) {
  $a::bar(1);
}

出力します(ここで実行します):

Warning: Declaration of Y::bar() should be compatible with X::bar($x) in /in/phAWB on line 12
Static dispatch:
X::bar() with x = 1
Y::bar()
Dynamic dispatch of a static method (surprise!):
X::bar() with x = 1
Y::bar()

(同等のコードは Java ではコンパイルされません。)

于 2015-04-20T15:38:45.200 に答える