php 方法重写:Declaration of should be compatible with that

上网搜索了一下,发现许多帖子基本都抄的一样,说什么这是由于 php5.3版本后,要求继承类必须在父类之后定义,如果父类定义在前,继承类在后,就不会出现这个错误。尤其是http://bugs.php.net/bug.php?id=46851上面还煞有介事的给出了正反例:

 代码如下 复制代码

<?php
// this code does trigger a strict message
error_reporting( E_ALL | E_STRICT );

class cc extends c { function test() { return null; } }
class c { function test( $a ) { return 1; } }

$cc = new cc();
?>
<?php
// this code does NOT trigger a strict message
error_reporting( E_ALL | E_STRICT );

class c { function test( $a ) { return 1; } }
class cc extends c { function test() { return null; } }

$cc = new cc();
?>

并且讨论了出错的情况多半是由于用_autoload()对类进行自动的include,导致基类的定义在后面,子类定义在前面。

我看了下自己的代码,虽然确实也用到了autoload,但是都是显式的先导入了几个基类,并不存在这样的情况,而且将上面的正反例子试了一下,都会出现E_STRICT的警告。

再看例子

 代码如下 复制代码
<?php
abstract class A {
// 方法无参数
public static function foo(){ echo 'bar'; }
}
 
abstract class B extends A {
// 方法有参数
public static function foo($str){ echo $str; }
}
?>

闪电似的

如上面的代码:类A中的foo方法无参数,类B在继承A后重写foo方法时加入了参数,因此会产生一个类似下面E_STRICT级别的警告:

Strict standards: Declaration of ... should be compatible with that of

 代码如下 复制代码
<?php
abstract class A {
// 方法无参数
public static function foo(){ echo 'bar'; }
}
 
abstract class B extends A {
// 方法有参数
public static function foo($str = NULL){ echo $str; }
}
?>

类B在重写foo方法时为新加入的参数指定一个默认值即可

真正原因:

其实如果子类重写方法的参数和基类不一样,只要给参数个默认值,使得编译器认为参数可以为空,保持重写方法与基类方法的函数签名相同就可以了。
经常用JAVA的同学肯定知道,在JAVA或者C++中,重写方法的函数签名本应该就和基类函数是一致的,我认为这也是符合自然规律的,因为override本来就是覆盖的意思嘛,既然覆盖了,那么就应该和原函数一致,不然怎么能“盖”的住呢~并且方法的重写多用在重写虚函数或者更明白的说就是重写接口的函数,如果重写的时候函数签名都不一致了,还要接口干嘛呢。。。
所以PHP的新版本中,我觉得定义这个E_STRICT的警告错误是很有用处的,要提醒程序员自己的重写方法到底对不对。

最后还是鄙视一下上面那些抄来抄去的帖子,如果某个语言连基类和子类定义的顺序都不能打乱,说明这个编译器非常有问题了,显然是bug。

时间: 2024-09-12 17:41:44

php 方法重写:Declaration of should be compatible with that的相关文章

php方法重写:Declaration of should be compatible with that

  如果你碰到php 方法重写,参数不同,报错: Declaration of should be compatible with that这种问题不防进入参考一下解决办法吧. 上网搜索了一下,发现许多帖子基本都抄的一样,说什么这是由于 php5.3版本后,要求继承类必须在父类之后定义,如果父类定义在前,继承类在后,就不会出现这个错误.尤其是http://bugs.php.net/bug.php?id=46851上面还煞有介事的给出了正反例: 代码如下   <?php // this code

PHP面向对象之方法重写

风来了.fox 因用到分表所以需要方法重写 报错: Declaration of ..... should be compatible with ..... 请用如下方式解决 class Model { /**设置分表名 * @param int $tableNum UID或表序号 * @param int $num 位数 * @return $this */ public function tableSplit($tableNum=0,$num=2){ $this->table($this->

JAVA学习(七):方法重载与方法重写、this关键字和super关键字

方法重载与方法重写.this关键字和super关键字 1.方法重载 重载能够使具有相同名称但不同数目和类型参数的类传递给方法. 注: 一是重载方法的参数列表必须与被重载的方法不同,并且这种不同必须足以清楚地确定要调用哪一个方法: 二是重载方法的返回值类型可以与被重载的方法相同,也可以不同,但是只有返回值类型不同不能表示为重载. 例如,最常用的println()方法在JDK的java.io.PrintStream中定义了十几种形式的重载,常用格式如下: public void println(in

对象-java的equals方法重写中的小问题

问题描述 java的equals方法重写中的小问题 public boolean equals(Object otherObject) { // a quick test to see if the objects are identical if (this == otherObject) return true; // must return false if the explicit parameter is null if (otherObject == null) return fal

java方法重写和super关键字

//java方法重写和super关键字 //在继承中,其实就是子类定义了和父类同名的方法 //就是方法,属性都是相通的 //重写限制: //被子类重写的方法不能拥有比父类方法更加严格的权限 //super:强行调用父类方法的执行 /*重载和重写的区别? * 重载是发生在一个类中 对权限没有要求 而且重载的方法参数可以不同 * 重写发生在继承汇总 被子类重写的方法不能拥有比父类方法更加严格的权限,重写的方法中参数名字完全相同 * */ class A{ public void tell(){ Sy

java方法重写实例分析_java

本文实例讲述了java方法重写,分享给大家供大家参考.具体分析如下: 一.方法的重写概述: 1.在子类中可以根据需要对从基类中继承来的方法进行重写. 2.重写的方法和被重写的方法必须具有相同方法名称.参数列表和返回类型. 3.重写方法不能使用比被重写的方法更严格的访问权限. 二.程序代码如下: class Person{ private int age; private String name; public void setAge(int age){ this.age = age; } pub

Java override方法重写学习笔记

重载Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同).那么如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载?结果是不行的.,我们可以用反证法来说明这个问题,因为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如,我们调用map.remove(key)方法时,虽然remove 方法有返回值,但是我们通常都不会定义接收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返

继承&amp;#183;方法重写

1.继承的概念:继承是类与类的一种关系:Java中的继承是单继承,只有一个父类. Java中是单继承的2.继承的好处:子类直接拥有父亲的所有属性和方法.---private修饰的无效!代码可复用.class 子类 extends 父类{--} 重写方法的规则: 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载. 2.返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载.如果在子类中写了一个只有返回类型不同的函数,将不是重写,且会报错 3.访问修饰符的限制一

虚方法重写

1.实例解析 控制台程序 class Program { static void Main(string[] args) { DerivedType derivedInstance = new DerivedType(); string line; while ((line = Console.ReadLine()) != null) { Console.WriteLine("----"); } } } public class BadlyConstructedType { prote