PHP面向对象之类的继承与构造函数

在我们是用来的继承时,总会在实例化对象的时候会问道,在我实例化对象的时候我是利用的自己的构造函数进行的实例,还是利用的父类的构造函数进行的实例化。

下面我们就来探讨一下这个问题。

1、如果父类有构造函数,子类没有构造函数,那么在子类实例化时确实会执行父类的构造函数。

看一个例子:

<?php
 
  class Employee
  {
        private $name;
        
        
        function __construct($nname)
        {
              $this->name = $nname;
        }
        
        function setName($name)
        {
              if($name == "")
              {
                   echo ‘the para is null‘;
              }else {
                  $this->name = $name;
              }
        }
        
        function getName()
        {
             return  $this->name;
        }
        
  }  

  class EngBoss extends Employee
  {
         function doStr()
         {
               echo ‘Do what you want to!!‘;
         }
  }
  
  $tian = new EngBoss("tian");
  echo $tian ->getName();
?>

执行结果:

tian

可以的出上面的结论。

2、但是如果子类也有构造函数,那么子类在实例化的时候不论父类构造函数是否存在都会去执行子类的构造函数。

<?php
 
  class Employee
  {
        private $name;
        
        
        function __construct($nname)
        {
              $this->name = $nname;
        }
        
        function setName($name)
        {
              if($name == "")
              {
                   echo ‘the para is null‘;
              }else {
                  $this->name = $name;
              }
        }
        
        function getName()
        {
             return  $this->name;
        }
        
  }  

  class EngBoss extends Employee
  {
         function __construct()
         {
                echo ‘say something!!‘;
         }
         
         function doStr()
         {
               echo ‘Do what you want to!!‘;
         }
  }
  
  $tian = new EngBoss("tian");
  echo $tian ->getName();
?>

运行结果:

say something!!

从运行结果中你会看到实例化的时候并没有对父类的name赋值,使得getName方法的返回结果为空。

3、当然如果你希望子类也能够执行父类的构造函数,那么你可以使用如下的解决方案:在上述代码中把子类的构造函数变成如下就好了:

 function __construct($name)
         {
                parent::__construct($name);
                echo ‘say something!!‘;
         }
         
或者是这样
function __construct($name)
         {
                //parent::__construct($name);
                Employee::__construct($name);
                echo ‘say something!!‘;
         }

运行结果:

say something!!tian

4、在创建类的层次体系中有时候会遇到这种情况:一个父方法要与静态类属性进行交互,但这些类属性有可能在子类中被覆盖了。这种情况会得到意料不到的结果。

<?php
 
  class Employee
  {
        private $name;
        public  static $times = 123;
        
        public static function watchTimes()
        {
            echo ‘watching !!!‘.self::$times;
        }
        
  }  

  class EngBoss extends Employee
  {
         public static $times = 456;
         function __construct($name)
         {
                //parent::__construct($name);
                Employee::__construct($name);
                echo ‘say something!!‘;
         }
         
  }
  
  echo EngBoss::watchTimes();
?>

运行结果:

watching !!!123

有人会感到吃惊但是结果却是是这样的。主要是由于self关键字会在编译时而不是在程序运行时确定其作用域。还好5.3版本之后对这个问题作了解决,使用static关键字。也就是如果想在运行时确定静态属性的作用域,应该使用static关键字。为此重写上面的方法:

<?php
 
  class Employee
  {
        private $name;
        public  static $times = 123;
        
        public static function watchTimes()
        {
            echo ‘watching !!!‘.static::$times;
        }
        
  }  

  class EngBoss extends Employee
  {
         public static $times = 456;
         function __construct($name)
         {
                //parent::__construct($name);
                Employee::__construct($name);
                echo ‘say something!!‘;
         }
         
  }
  
  echo EngBoss::watchTimes();
?>

结果是:

watching !!!456

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。