热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php面向对象中子类中重载父类详解

因为在PHP中不能存在同名的函数,所以在同一个类中也就不能定义重名的方法,这里所说的重载是指在子类中可以定义和父类同名的方法从而覆盖从

因为在PHP中不能存在同名的函数,所以在同一个类中也就不能定义重名的方法,这里所说的重载是指在子类中可以定义和父类同名的方法从而覆盖从父类中继承过来的方法。

子类中重载父类的方法,实例代码如下:

  1.       class Person{ 
  2.                                                                 
  3.            public $name;       
  4.                                                                
  5.            public function __construct($name="" ){ 
  6.                 $this->name =$name
  7.                                                                         
  8.            } 
  9.            public  function say(){ 
  10.                 echo "我叫".$this->name  ;  
  11.            } 
  12.                                                                    
  13.  } 
  14.  ?> 
  15.  
  16.       class Student extends Person{ 
  17.                                                                 
  18.            public $name;               
  19.                                                                
  20.            public function __construct($name=""){ 
  21.                 $this->name =$name
  22.                                                            
  23.            } 
  24.  //这里定义了一个和父类中同名的方法,将父类中的说话方法覆盖并重写 
  25.            public  function say(){ 
  26.                 echo "我叫".$this->name .",今年25岁了" ;  
  27.            } 
  28.                                                                    
  29.  } 
  30.  ?> 

重写方法与访问权限

子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限,如果父类中的方法的访问权限是protected,那么子类中重写的方法的权限就要是protected或者public;    如果父类中的方法是public,那么子类要重写的方法的权限就只能是public。也许这也就是为什么子类可以继承父类的私有成员,但却不能使用的原因吧。

重写时的参数数量

子类可以拥有与父类不同的参数数量,如下面的构造方法中,多添加了一个参数$age,实例代码如下:

  1.       class Student extends Person{  
  2.                                                  
  3.            public $name;       
  4.           public $age;           
  5.                                                  
  6.            public function __construct($name="",$age=25){   
  7.                 $this->name =$name;  
  8.                 $this->age =$age;  
  9.           }  
  10.           public  function say(){  
  11.                 echo "我叫".$this->name .",今年".$this->age."岁了" ;    
  12.            }    
  13.                                                     
  14.  }   
  15.  ?> 

构造函数重写

上面提到的“重写时的参数数量”就已经实现了子类对父类的构造函数进行了重写,但这不是一种好的写法,如果仔细观察,你会发现,上面子类Student对父类Person构造函数的重写,其实就是在父类的构造函数的基础上多添加了一个参数,但是又把父类原有的参数照写一遍,因为父类Person的构造函数只有一个参数,所以我们照写一遍不觉得有什么麻烦,但是如果参数不止一个,而是几个或者更多,那么你就会发现它的繁琐之处,那么有没有办法可以简化这个问题呢?答案是肯定的,可通过使用"parent::方法名" 在子类的重载方法中调用父类中被它覆盖的方法,如使用"parent::__construct()"调用父类中被覆盖的构造方法,其它方法的类似,于是上面的代码可以简化为:

  1.       class Student extends Person{  
  2.                                        
  3.            public $name;      
  4.            public $age;           
  5.                                        
  6.           public function __construct($name="",$age=25){  
  7.               parent::__construct($name,$age);  
  8.               $this->age =$age;   
  9.          }  
  10.            public  function say(){   
  11.              parent::say();  
  12.               echo ",今年".$this->age."岁了" ;    
  13.           }    
  14.                                            
  15.  }   
  16.  ?> 

下再看一个实例

PHP5重写方法

先设置一个父类,这个父类是 “Dog”类,这个类描述了dog的特性,Dog有2个眼睛,会跑,会叫。就这样描述先,我养了一直狗,是只小狗,符合Dog类的特性,但有所不同,我的小狗有名字,我的小狗太小了,不会大声的叫,只会哼哼,我们用继承的概念去实现这个设计,代码如下:

  1. // 狗有两只眼睛,会汪汪叫,会跑. 
  2. class  Dog { 
  3.  protected  $eyeNumber =2; //属性 
  4.  //返回封装属性的方法. 
  5.  public function getEyeNumber(){  
  6.   return $this->eyeNumber; 
  7.  } 
  8.  //狗会叫  
  9.  public function  yaff(){ 
  10.   return  "Dog yaff, wang ..wang .."
  11.  } 
  12.  //狗会跑 
  13.  public function  run(){ 
  14.   return  "Dog run..running ..."
  15.  } 
  16. $dog = new Dog(); 
  17. echo "dog have ".$dog->getEyeNumber()." eyes. 
    "
  18. echo $dog->yaff() ."
    "
    .$dog->run(); 
  19. echo  "

    "
  20. //这是我的小狗叫"狗狗",它很小.不会汪汪叫,只会哼哼哼.. 
  21. class MyDog extends Dog { 
  22.  private $name = "狗狗"
  23.  public function getName(){ 
  24.   return $this->name; 
  25.  } 
  26.     public function  yaff(){ 
  27.   return  $this->name." yaff, heng...heng .."
  28.  }  
  29. $myDog = new MyDog(); 
  30. echo $myDog->getName()." have ".$myDog->getEyeNumber()." eyes. 
    "
  31. echo $myDog->yaff() ."
    "
    .$myDog->run(); 
  32. ?> 
  33. //程序运行结果: 
  34. //dog have 2 eyes.  
  35. //Dog yaff, wang ..wang .. 
  36. //Dog run..running ... 
  37. //狗狗 have 2 eyes.  
  38. //狗狗 yaff, heng...heng .. 
  39. //Dog run..running ... 

重写方法与访问权限

子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限,父类为public 子类为 private时,实例代码如下:

  1. // 简化dog类和mydog类,演示重写的访问权限. 
  2. class Dog { 
  3.  protected  $eyeNumber =2; //属性 
  4.  //返回封装属性的方法. 
  5.  public function getEyeNumber(){  
  6.   return $this->eyeNumber; 
  7.  }  
  8. class MyDog extends Dog { 
  9.  protected function getEyeNumber(){  
  10.   return $this->eyeNumber; 
  11.  }  
  12. /* 
  13. class MyDog extends Dog { 
  14.  private function getEyeNumber(){  
  15.   return $this->eyeNumber; 
  16.  }  
  17. } 
  18. */ 
  19. ?> 
  20. //程序运行结果: 
  21. //Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:PHPProjectstest.php on line 15 

父类为public子类为protected时,实例代码如下:

  1. // 简化dog类和mydog类,演示重写的访问权限. 
  2. class Dog { 
  3.  protected  $eyeNumber =2; //属性 
  4.  //返回封装属性的方法. 
  5.  public function getEyeNumber(){  
  6.   return $this->eyeNumber; 
  7.  }  
  8. class MyDog extends Dog { 
  9.  private function getEyeNumber(){  
  10.   return $this->eyeNumber; 
  11.  }  
  12. ?> 
  13. //程序运行结果: 
  14.  //Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:PHPProjectstest.php on line 15 

重写时的参数数量

子类可以拥有与父类不同的参数数量,这点与java不同,PHP是弱类型语言,实例代码如下:

  1. // 简化dog类和mydog类,演示重写方法的参数. 
  2. class  Dog { 
  3.  protected  $eyeNumber =2; //属性 
  4.  //返回封装属性的方法. 
  5.  public function getEyeNumber(){  
  6.   return $this->eyeNumber; 
  7.  }  
  8. class MyDog extends Dog { 
  9.  //重写的方法与父类的方法有不同的参数数量. 
  10.  public function getEyeNumber($eys){ 
  11.   $this->eyeNumber = $eys
  12.   return $this->eyeNumber; 
  13.  }  
  14. $myDog = new MyDog(); 
  15. echo "my dog hava ".$myDog->getEyeNumber(3) ." eyes."
  16. //啸天犬..哈.. 
  17. //下面这句会报一个丢失参数的错误. 
  18. //echo "my dog hava ".$myDog->getEyeNumber() ." eyes."; 
  19. ?> 
  20. //程序运行结果: 
  21. //my dog hava 3 eyes. 

构造函数重写

下面这个例子中,父类和子类都有自己的构造函数,当子类被实例化时,子类的构造函数被调用,而父类的构造函数没有被调用,请对比第一节的构造函数继承,实例代码如下:

  1. //2-2 / extends1.php 
  2. //构造函数继承的问题. 
  3. class Animal{ 
  4.  public $legNum = 0;  
  5.  public function __construct(){ 
  6.   $this->legNum = 4; 
  7.   echo "I am an animal
    "
  8.  } 
  9. class Dog1 extends Animal { 
  10.  public function __construct(){ 
  11.   $this->legNum = 4; 
  12.   echo "I am a Dog .
    "
  13.  } 
  14. $dog1 = new Dog1(); 
  15. echo "
    "
  16. echo  "legNum is ".$dog1->legNum; 
  17. /* 
  18. 实例化子类时.构造函数被调用了. 
  19. */ 
  20. ?> 
  21. //程序运行结果: 
  22. //I am a Dog .   
  23. //legNum is 4 

注:这点和Java不同,在java中构造函数是不能被继承的,而且子类实例化时,子类的构造函数被调用,父类的构造函数也会调用.


推荐阅读
  • 本文介绍了拍摄高质量Vlog所需的设备,包括索尼A7 III相机、蔡司镜头、罗德麦克风、单反稳定器、苹果手机及其配件、灯光设备等。此外,还探讨了后期制作所需的软件工具,如剪辑、特效和调色软件。无论你是业余爱好者还是专业创作者,选择合适的设备至关重要。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 探讨一个老旧 PHP MySQL 系统中,时间戳字段不定期出现异常值的问题及其可能原因。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 郑州大学在211高校中的地位与排名解析
    本文将详细解读郑州大学作为一所位于河南省的211和双一流B类高校,在全国211高校中的地位与排名,帮助高三学生更好地了解这所知名学府的实力与发展前景。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 优化ASM字节码操作:简化类转换与移除冗余指令
    本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 电子元件封装库:三极管、MOS管及部分LDO(含3D模型)
    本资源汇集了常用的插件和贴片三极管、MOS管以及部分LDO的封装,涵盖TO和SOT系列。所有封装均配有高质量的3D模型,共计96种,满足日常设计需求。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 小红书提高MCN机构入驻门槛,需缴纳20万元保证金
    近期,小红书对MCN机构的入驻要求进行了调整,明确要求MCN机构在入驻时需缴纳20万元人民币的保证金。此举旨在进一步规范平台内容生态,确保社区的真实性和用户体验。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
author-avatar
CCTV2财经2677
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有