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类型的方法

时间: 2024-11-04 18:35:34

PHP类方法重写原则的相关文章

重写原则用多态来解释

1.子类的访问修饰符要大于或者等于父类的范围 class A{ public void m(){} } class B extends A{ void m(){} } 这个时候子类的访问范围比父类小,我们姑且算它是对的进行反推 A a =new B();//向上转型 a.m();//a对象是由A类申明,就可以去调用A中的方法,m()在任意位置都可以访问. a.m();//调用方法的时候具体的执行看子类,就可以去调用B类中的m(),可以在本身+ 原文地址:https://www.cnblogs.c

浅谈equals重写

equals的简单了解: Object中的equals方法用于检测一个对象是否等于另外一个对象. Object类中,判断两个对象是否引用同一个对象实现equals方法,源码如下: public boolean equals(Object obj) { return (this == obj); } 从源码可以看出,对于复合数据类型之间进行equals比较,在没有重写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(=

PHP OOP 面向对象的特性

一. OOP 的封装 隐藏对象的字段和实现细节,仅对外公开接口,控制在程序中字段的读和修改的访问级 别:将抽象得到的数据和行为(或功能)相结合,形成 一个有机的整体,也就是将数据与 操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员. 字段的作用域 1.public 公共的 (类外可以访问) 2.private 私有的 (类内可以访问) 3.protected 受保护的 (类内和子类可以访问,类外不可访问) 创建使用了私有的字段,这样外部就无法访问了 class C

第十八章 面向对象的特性

学习要点:1.OOP 的封装2.OOP 的继承3.OOP 的多态 面向对象的三个主要特性是封装.继承和多态. 一.OOP的封装 隐藏对象的字段和实现细节,仅对外公开接口,控制在程序中字段的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员. 字段的作用域1.public 公共的(类外可以访问)2.private 私有的(类内可以访问)3.protected 受保护的(类内和

[学习笔记]Java异常机制

概述 异常 程序在执行时出现的不正常情况,是对问题的描写叙述.将问题进行对象的封装. Java中的异常,就是对不正常情况进行描写叙述后的对象体现. 异常体系 Throwable |--Error |--Exception |--RuntimeException 当中Error类处理严重异常,一般不编写针对性的代码对其进行处理. Exception类处理非严重异常,能够使用针对性的处理方式进行处理. 不管Error或者Excption都具有一些共同的属性和方法,比方不正常情况的信息和引发原因等.

类-Class

相关概念 类:是对事物的抽象,人/动物/机器,如汽车模型:创建实例的模板对象:是类的一个实例,如大客车:则是一个一个具体的对象,各个实例拥有的数据相互独立,互不影响范例说明:汽车模型可以对汽车的特征和行为进行抽象,然后可以实例化为一台真实的汽车实体出来方法:人会走,会思考,定义一个类的各个功能,类中定义的函数数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据 继承:即一个派生类(derived class)继承基类(base class)的字段和方法.继承也允许把一个派生类的对象作为

java基础小总结(2)

Day07: 1.如果局部变量和全局变量都有相同的数据类型和变量名,先调用局部变量,实现就近原则: 2.匿名对象由于局限性的原因,一般只调用一次,且只是当作为实际参数传递的时候使用: 3.面向对象语言的三大基本特征:封装,继承,多态 4.封装的好处:安全,方便,用private(只能在本类中访问)体现: 5.构造函数是为了显示初始化:是没有返回值类型的 6.在构造函数可以调用一般函数,但是在一般函数中不可以调用构造函数: 7.构造函数定义的细节: 1.构造函数是用来创建对象的,它不需要书写返回值

php面向对象特性三

OOP继承 继承是为了一个基类得到一个或多个类的机制. 继承自另一个类的类被称为该类的子类.这种关系通常用父类和子类来比喻.子类将继承父类的特性.这些特性由属性和方法组成.子类可以增加父类之外的新功能,因此子类是父类的"扩展". 在PHP中,类继承通过extends关键字实现.继承自其他类的类成为子类或派生类,子类所继承的类成为父类或基类.(PHP只支持单继承,PHP不支持方法重载). class Computer{ private $_name = "联想"; p

20165315 第三周学习总结

20165315 第三周学习总结 本周学习中遇到的问题和解决过程 在编写书上第四章例子5的代码时,我发现无法直接使用javac -d bin src/Example4_5.java命令使该代码的字节码文件直接放入bin目录 解决方法: 经过询问老师和同学,得知问题出在无法一同编译另外两个源文件,输入如下图所示的代码即可编译并运行成功 在编写书上第四章例子17和例子18的代码时,无法通过编译,显示如下图错误: 解决方法: 经过多次尝试和细心检查后,我发现是在编写时大意,将setSides编写为se