侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

详解php中的类与对象(继承)

php  /  管理员 发布于 7年前   163

简介

在php中,类型的继承使用extends关键字,而且最多只能继承一个父类,php不支持多继承。

class MyClass  {  public $dat = 0;  public function __construct($dat) {   $this->dat = $dat;  }  public function getDat() {   return "$this->dat\n";  } } class MySubClass extends MyClass {  public function getDat() {   return "dat: $this->dat\n";  } } $a = new MyClass(3); $b = new MySubClass(4); echo $a->getDat();  // 3 echo $b->getDat();  // dat: 4 

方法覆盖

包括构造函数在内,子类可以重新定义同名的类方法以覆盖父类方法。覆盖时遵循以下规则:

1.除构造函数之外,其他函数在覆盖时,函数的参数列表必须相同

2.包括构造函数在内,方法被覆盖后,调用子类方法时并不会自动调用父类方法

3.如果父类要禁止方法被子类覆盖,可以使用final来声明方法,这时如果子类仍要覆盖父类方法,将会出错

class MyClass  {  private $name = "";  public $num = 0;  public $str = "";  public function __construct($name) {   $this->name = $name;   $this->num = 100;   $this->str = "none";  }  public function getName() {   return $this->name;  } } class MySubClass extends MyClass {  public function __construct($name, $str) {   parent::__construct($name);    // 调用父类方法   $this->num = "0";   $this->str = $str;   echo parent::getName()."\n";    // 调用父类方法  }  public function getName() {   return parent::getName()."$this->str\n"; // 调用父类方法  } } $b = new MySubClass("myName", true);  // myName echo $b->getName();          // myName1 class MyClass  {  final public function getName() {  } } 

属性重定义

在子类中,可以访问父类中的public和protected属性成员,除非重定义了同名的自有属性,这时,父类中的属性将无法访问。

方法则不同,子类对方法进行覆盖后,仍然可以访问到父类方法。

class MyClass  {  public $a = 1;  protected $b = 2;  private $c = 3;  public function f1() {   echo "MyClass f1\n";   echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";  }  protected function f2() {   echo "MyClass f2\n";   echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";  }  private function f3() {   echo "MyClass f3\n";  } } class MySubClass extends MyClass  {  public $b = 22;  public $c = 33;  public function f1() {   echo "MySubClass f1\n";   // 继承到父类中的$a属性,直接使用   echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";   // 调用父类中的同名方法   parent::f1();   // 继承到父类中的f2()方法,直接使用   $this->f2();  }  // 父类的f3()是私有的,这里的定义与父类无关  public function f3() {   echo "MySubClass f3\n";  } } $b = new MySubClass; $b->f1();echo "\n"; /* MySubClass f1 $a:1; $b:22; $c:33; MyClass f1 $a:1; $b:22; $c:3; MyClass f2 $a:1; $b:22; $c:3; */ $b->f3();echo "\n"; /* MySubClass f3 */ 

重定义父类(同名)属性时,属性的可访问性可以变得更开放,但不能更严格,也就是说,父类中的public属性,不能在子类中修改为private属性。

如果通过子类对象调用父类方法,那么该父类方法在访问属性时,对于重定义了的同名属性,public和protected的属性将访问到子类版本,private属性将访问到父类版本。也可以理解为,public和protected属性可以被重定义(父类的版本被重定义,从而不存在了),而private并未被重定义(父类中的属性仍然存在,通过父类方法进行访问,与子类中是否有同名属性毫不相干)。

class MyClass  {  public $a = 1;  protected $b = 2;  private $c = 3;  public function f1() {   echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";  } } class MySubClass extends MyClass  {  public $a = 11;   // 必须为public  protected $b = 22; // 必须为protected或public  private $c = 33;    public function f2() {   echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";  } } $b = new MySubClass; $b->f1(); // $a:11; $b:22; $c:3; $b->f2(); // $a:11; $b:22; $c:33; 

范围解析操作符 ::

又冒号常用于访问类常量、类静态变量,也用于在方法覆盖时调用父类版本。与其搭配的还包括parent、self、static等关键字。

class MyClass  {  const Name0 = "MyClass";  // 类常量  public static $id0 = 0;  // 类变量  public function put() {  // 将被子类覆盖的方法   echo "MyClass put()\n";  } } class MySubClass extends MyClass  {  const Name1 = "MySubClass";  public static $id1 = 1;   public function put() {   parent::put();        // 调用父类版本的对象方法   echo parent::Name0 . "\n";  // 父类常量   echo parent::$id0 . "\n";   // 父类变量   echo self::Name1."\n";    // 子类常量   echo self::$id1 . "\n";    // 子类变量   echo static::Name1 . "\n";  // 子类常理   echo static::$id1 . "\n";   // 子类变量  } } $a = "MyClass"; $ca = new MyClass; $cb = new MySubClass;  $cb->put(); echo MyClass::Name0 . "\n"; echo MyClass::$id0 . "\n"; echo $a::Name0 . "\n"; echo $a::$id0 . "\n"; echo $ca::Name0 . "\n"; echo $ca::$id0 . "\n"; 

在子类中访问父类中的成员时,应避免直接使用父类类名,而应使用parent::,以免破坏父类的封装性。

final

声明为final的方法不能被子类覆盖,如果类声明为final,则此类不能被继承。

// 声明为final的类不能被继承 final class MyClass {  private $dat;  public function __construct($dat) {   $this->dat = $dat;  }  // final方法不能被覆盖,不过此类已经是final类,方法无必要在声明为final了  final public function getDat() {   return $this->dat;  } }

总结

以上所述是小编给大家介绍的php中的类与对象(继承),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!

您可能感兴趣的文章:

  • PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
  • PHP高级对象构建 工厂模式的使用
  • PHP面向对象教程之自定义类
  • php中类和对象:静态属性、静态方法
  • PHP面向对象的进阶学习(抽像类、接口、final、类常量)
  • php使用变量动态创建类的对象用法示例
  • php判断对象是派生自哪个类的方法
  • PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
  • PHP实现基于面向对象的mysqli扩展库增删改查操作工具类
  • PHP面向对象程序设计之类常量用法实例
  • php对象工厂类完整示例


  • 上一条:
    PHP单文件和多文件上传实例
    下一条:
    PHP基于二分法实现数组查找功能示例【循环与递归算法】
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客