PHP类继承 extends使用介绍

出来工作这么久了,项目经验倒是不少,但是当问及底层的东西时候,常常是一言不发了。现在项目设计底层的东西越来越少,可以说是真正用到的也就是那么一点,真正核心的东西都已经被框架封装好了。总感觉自己一直进步很慢,关于底层设计思想,常常也只可意会。随着时间的流逝,我们常常会感慨书到用时方恨少了,接下来一定要恶补设计思想了。

今天先来复习一下类继承。

类继承很重要,作为程序员也基本每天都会和他打交道,但是有些东西你真的都知道吗?下面是从官网上面看到的。

一个类可以在声明中用 extends,关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。

被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。

当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。

关于基本的概念想必大家都会知道,但是对于final和parent::在项目中我还真没有怎么使用过,惭愧啊。

下面主要说一下这两个关键字的用途吧。

Final 关键字

PHP 5新增的一个关键字,如果父类中的方法被声明为 final,则子类无法覆盖该方法。同样如果一个类被声明为 final,则不能被继承。

需要注意的是: 属性不能被定义为 final,只有类和方法才能被定义为 final。

范围解析操作符(::)

当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。这种机制也作用于构造函数和析构函数,重载以及魔术方法。

下面是调用父类的方法的一个示例:

  1. <?php
  2. class MyClass
  3. {
  4. protected function myFunc() {
  5. echo "MyClass::myFunc()\n";
  6. }
  7. }
  8. class OtherClass extends MyClass
  9. {
  10. // 覆盖了父类的定义
  11. public function myFunc()
  12. {
  13. // 但还是可以调用父类中被覆盖的方法
  14. parent::myFunc();
  15. echo "OtherClass::myFunc()\n";
  16. }
  17. }
  18. $class = new OtherClass();
  19. $class->myFunc();
  20. /**
  21. * 输出结果 ->
  22. * MyClass::myFunc()
  23. * OtherClass::myFunc()
  24. */
  25. ?>

当在类定义之外引用到这些项目时,要使用类名。

::class 自 PHP 5.5 起,关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。这些可能就是以后要讨论的话题了,关于这个概念那就是以后要讨论的了,现在我们还在使用php5.3。

不过说句实话,有一些关键字在小项目中确实是很难使用,不过我想多了解一些总还是需要的。尤其是当你使用一些第三方的类库时候,当你细细研究他的程序逻辑,你总能学点东西。尽管有些东西你长时间不用,可能就忘记了,但是毕竟他曾经在你脑海里经过过,总会为以后的人生留点痕迹。

最后废话不多说了,分享一段范围解析操作符(::)应用的代码,你们也来感受下:

  1. <?php
  2. class cA
  3. {
  4. /**
  5. * 直接使用的测试属性的默认值
  6. */
  7. protected static $item = 'Foo';
  8. /**
  9. * 间接使用的测试属性的默认值
  10. */
  11. protected static $other = 'cA';
  12. public static function method()
  13. {
  14. print self::$item."\r\n";
  15. print self::$other."\r\n";
  16. }
  17. public static function setOther($val)
  18. {
  19. self::$other = $val;
  20. }
  21. }
  22. class cB extends cA
  23. {
  24. /**
  25. * 重定义测试属性的默认值
  26. */
  27. protected static $item = 'Bar';
  28. public static function setOther($val)
  29. {
  30. self::$other = $val;
  31. }
  32. /**
  33. * 不重新声明 method()方法
  34. */
  35. }
  36. class cC extends cA
  37. {
  38. /**
  39. * 重定义测试属性的默认值
  40. */
  41. protected static $item = 'Tango';
  42. public static function method()
  43. {
  44. print self::$item."\r\n";
  45. print self::$other."\r\n";
  46. }
  47. /**
  48. * 不重新声明 setOther()方法
  49. */
  50. }
  51. class cD extends cA
  52. {
  53. /**
  54. * 重定义测试属性的默认值
  55. */
  56. protected static $item = 'Foxtrot';
  57. /**
  58. * 不重新声明 任何方法来实现上述过程
  59. */
  60. }
  61. cB::setOther('cB'); // cB::method()!
  62. cB::method(); // cA::method()!
  63. cC::setOther('cC'); // cA::method()!
  64. cC::method(); // cC::method()!
  65. cD::setOther('cD'); // cA::method()!
  66. cD::method(); // cA::method()!
  67. //phpfensi.com
  68. /**
  69. * 输出结果 ->
  70. * Foo
  71. * cB
  72. * Tango
  73. * cC
  74. * Foo
  75. * cD
  76. */
  77. ?>

PHP extends类继承代码示例:

  1. < ?php
  2. class a{
  3. public $x;
  4. public $y;
  5. function __construct($x=0,$y=0){
  6. $this->x=$x;
  7. $this->y=$y;
  8. }
  9. function getx(){
  10. return $this->x;
  11. }
  12. function gety(){
  13. return $this->y;
  14. }
  15. function __destruct(){}
  16. }
  17. class a2 extends a{}
  18. /*extends是一个继承函数*/
  19. $b2=new a2(10,10);
  20. echo $b2->getx()."<br>";
  21. echo $b2->gety();
  22. ?>

以上介绍的内容就是PHP extends类继承的全部实现步骤。