热门标签 | 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中构造函数是不能被继承的,而且子类实例化时,子类的构造函数被调用,父类的构造函数也会调用.


推荐阅读
  • JFinal 配置详解:自定义配置类
    本文详细介绍了如何通过继承 JFinalConfig 类来自定义配置,主要涵盖五个核心方法的实现和功能说明。 ... [详细]
  • 深入理解Kafka架构
    本文将详细介绍Kafka的内部工作机制,包括其工作流程、文件存储机制、生产者与消费者的具体实现,以及如何通过高效读写技术和Zookeeper支持来确保系统的高性能和稳定性。 ... [详细]
  • 深入解析宋惠洪的《渔父词》,探讨其文学价值与艺术特色。 ... [详细]
  • 本文介绍如何利用QFileSystemModel进行目录的浏览、创建及删除操作,并提供了一个简单的对话框界面实现。 ... [详细]
  • 探讨在表单提交后,如何有效获取未被选中的复选框元素的值。 ... [详细]
  • 本文探讨了如何在Java后端配置CORS以支持或禁止携带凭证(如Cookie),并提供了前后端的具体实现方法。 ... [详细]
  • 将基于Web的互动多媒体体验引入手机和平板电脑历来面临诸多挑战,如性能瓶颈、API兼容性和HTML5音频及视频播放限制等问题。本文探讨了如何克服这些障碍,为《霍比特人:史矛革之战》打造了一个移动优先的沉浸式网络体验。 ... [详细]
  • 使用Solr从MySQL导入数据构建全量索引
    为了更好地掌握Solr的各项功能,本文档将在本地Windows环境中演示如何从MySQL数据库中导入数据至Solr,并构建全量索引。这将有助于开发者熟悉Solr的数据处理流程,尤其是在无法直接在生产服务器上进行实践的情况下。 ... [详细]
  • 本文介绍了一种使用inotifywait和rsync工具在两台服务器之间实现自动且高效的文件同步方案。通过设置SSH无密码登录,安装必要的软件,并配置inotify以优化性能,最终构建了一个实时响应文件变动并自动同步至备份节点的系统。 ... [详细]
  • MySQL中的Anemometer使用指南
    本文详细介绍了如何在MySQL环境中部署和使用Anemometer,以帮助开发者有效监控和优化慢查询性能。通过本文,您将了解从环境准备到具体配置的全过程。 ... [详细]
  • python爬虫Demo
    1爬虫功能:爬取某域名下所有网页,比如爬取python文档 https:docs.python.orgzh-cn3 ,爬取之后, ... [详细]
  • 深入解析宋代著名诗人张先的《御街行》,探讨其艺术魅力与文化价值。 ... [详细]
  • PHP 数据类型详解及其应用场景
    本文详细介绍了PHP中的八种数据类型,并探讨了它们各自的应用场景,帮助开发者更好地理解和使用这些数据类型。 ... [详细]
  • C#反射reflection
    C#shanzm目录简介引入1.新建类库2.类库的使用3.反射反射实例1反射实例2反射实例3简介反射(reflection)是什么?在《精通C#》中是这么说的“反射就是一个运行库发 ... [详细]
  • 如何在HTML中为两个不同的div设置不同的overflow属性
    探讨在Web前端开发中,如何使用CSS的overflow属性来实现两个div的不同滚动效果,特别是当设计一个弹出窗口时的需求处理。 ... [详细]
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社区 版权所有