PHP方法重写

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP方法重写相关的知识,希望对你有一定的参考价值。

a.php里有一个类
class A()
public function test()echo "这是test方法";


如果我想在b.php里重写a.php 里的test方法,怎么实现?

参考技术A 直接extends类A然后同名函数覆盖就行了
调用的就是重写后的test
如果要调用重写前的用parent,例:parent::test();追问

怎样在父类中调用子类重写后的方法???

追答

没法调用

参考技术B class B extends A
public function test()echo "这是test方法";

追问

a.php里有一个类
class A()
public function test1() $this->test();//
public function test()echo "这是test方法";


那么test1调用的是重写前的test()还是重写后的test()??我怎样才能调到重写后的方法??

追答

重写后的

本回答被提问者采纳

PHP类方法重写原则

可能我们日常工作中很少用到这块知识点,但我还是喜欢把遇到的却不清楚的知识点摸清

PHP的类方法重写规则

1、final修饰的类方法不可被子类重写

final修饰的类方法不可被子类重写 即便final private方法无法被继承 子类仍不能对齐进行重写

 1 class FinalMethod
 2 {
 3     //可继承不可重写
 4     final public function finalPublic()
 5     {
 6         echo "can be inherited, but be overrided";
 7     }
 8     //可继承不可重写
 9     final protected function finalProtected()
10     {
11         echo "can be inherited, but be overrided";
12     }
13     //不可继承不可重写 虽然子类继承不到父类的private方法 但同时也会被final限制无法重写
14     final private function finalPrivate()
15     {
16         echo "can not be inherited or be overrided";
17     }
18     //虽然不可继承 但子类里可重写此方法
19     private function private()
20     {
21         echo "can not be inherited ,but be overrided";
22     }
23 }
24 
25 class Override extends FinalMethod
26 {
27     //error
28     public function finalPublic()
29     { 
30     }
31     //error
32     protected function finalProtected()
33     {
34     }
35     //error
36     private function finalPrivate()
37     {
38     }
39     //correct
40     public/protected/private function private()
41     {
42         //子类继承父类重写父类方法时访问级别只能更加宽松 不可更为严格
43     }
44 }
2、PHP是否重写父类方法只会根据方法名是否一致判断(5.3以后重写父类方法参数个数必须一致)

这里并不是说方法参数无任何作用 PHP无重载机制 所以判断是不是重写只会通过方法名(C/C++不仅要方法名相同,参数也相同时才被视为重写,否则即为重载,即新定义了一个多态函数的态) 当方法名相同时即被认为是在重写父类方法,5.2可以参数不同,5.3以后参数需和父类方法一致,且都追寻继承访问级别的规则。

 1 class Father
 2 {
 3     public function index($args_1)
 4     {
 5     }
 6 }
 7 
 8 class Child extends Father
 9 {
10     //5.3以后重写方法必须与父类保持参数个数相同
11     public function index($args_1, $args_2)
12     {
13         //在C/C++中此为重载非重写,因为C/C++具有标准的多态机制,会因参数不同而视为某一方法的另一种态
14         //but在php中此依然为重写 但5.3以后此为非法 必须与父类的方法参数个数保持一致
15     }
16     //5.3以后重写方法必须与父类保持参数个数相同
17     private function index($args_1, $args_2)
18     {
19         //C/C++会因为参数不同于父类方法而视为重载,即新定义了一个函数的态,所以不会受到继承访问权限的限制
20         //但php仍然会被视为对父类方法的重写,会受到继承访问权限的升降规则限制
21     }
22 }
3、重写时访问级别只可以等于或者宽松于父类 不可提升访问级别

父类的public方法不能被子类重写为protected或者private,protected方法不能被重写为private,可以宽松er,不可以严格er

 1 class Father
 2 {
 3     public function index()
 4     {
 5     }
 6 }
 7 
 8 class Child extends Father
 9 {
10     protected/private function index()
11     {
12        //访问权限提升 错误 
13        //父类为public 则子类重写也只能为public
14        //父类为protected 则子类可为public/protected
15        //父类为private 则子类public/protected/private皆可
16     }
17 }

其实关于访问级别继承规则有很多有趣的地方

private在我们常识中是无法被继承的,子类拿不到,但其访问级别已是最高,所以你在子类中可以写成private protected public 仿佛是我们自己重新定义了一个函数一样,这点在5.2版本之前尤其突出,因为5.2之前的版本在继承重写父类方法是可以不保持参数个数相同,但5.3以后加强了这方面的限制,参数个数必须与父类相同

注:

    子类实现父类的抽象方法或某类实现接口的方法时其实仍属于继承关系,仍追寻访问等级只能降低不可提升的规则

    而且

 抽象方法不可被声明为private,abstract修饰的方法肯定是用于继承实现的,所以只能是public或者protected 接口的方法声明必须为public,interface里声明的方法也肯定是被继承实现的,且只能是public, implements  此接口的类也指定重写成public类型的方法

 

以上是关于PHP方法重写的主要内容,如果未能解决你的问题,请参考以下文章

PHP类方法重写原则

Laravel要重写Router.php里面的`auth`方法,应该在啥地方重写

php子类能不能重写父类的private方法?

PHP对象4: final 不允许重写方法或不允许继承类

php 三大特点:封装,继承,多态

记录 nginx和php安装完后的URL重写,访问空白和隐藏index.php文件的操作方法