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

时间: 2024-12-18 23:08:33

PHP面向对象之类的继承与构造函数的相关文章

C++ Primer 学习笔记_31_面向对象编程(2)--继承(二):继承与构造函数、派生类到基类的转换 、基类到派生类的转换

C++ Primer 学习笔记_31_面向对象编程(2)--继承(二):继承与构造函数.派生类到基类的转换 .基类到派生类的转换 一.不能自动继承的成员函数 构造函数 拷贝构造函数 析构函数 =运算符 二.继承与构造函数 基类的构造函数不被继承,派生类中需要声明自己的构造函数. 声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化调用基类构造函数完成(如果没有给出则默认调用默认构造函数). 派生类的构造函数需要给基类的构造函数传递参数 #include <iostream

Lua面向对象----类、继承、多继承、单例的实现

(本文转载)学习之用,侵权立删! 原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&utm_medium=referral lua面向对象实现: 一个类就像是一个创建对象的模具.有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例.lua则没有类的概念,每个对象只能自定义行为和形态.不过,要在lua中模拟类也并不困难. lua中,面向对象是用元表这个机制来实现.

javascript 中面向对象实现 如何继承

继承,同样不是真正严格意义上面向对象的继承,而是通过javascript中的原型链关系实现函数之间的属性,方法共享.下面简单分享几种封装的方法. 既然说到继承,我们必须有一个基类 1 2 3 4 5 6 7 8 9 function Person(){ this.eat=function(){ return '吃食物'; } } Person.prototype.sport=function(){ return '运动'; } Person 这个基类包含了2个属性,吃和运动.但是奇怪的是在构造函

C#面向对象编程 封装 继承 多态

  C#面向对象编程 什么是面向对象? 面向对象编程是上个实际六十年代继面向结构编程之后提出的一个新的编程思想 封装,继承,多态 封装,继承,多态是面向对象编程的核心: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型 意义是:保护数据不被破坏(例如一台电视机我们能使用它但是不能随意改变内部的电路) 关键字:private,public,protected,internal Public string name;

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的影响,单单是自己的念想受到了一定得局限,想法不能够像平地而起的高楼大厦建成一样.可是那大楼也是有烂尾的呀,我觉得最重要的还是外在环境与个人观念的先决条件,决定了拖延症的症状的好坏,有那么一些人,它也有拖延症,但是它在拖的中间,想的更多,看的更远.事情在做的时候更加有条不紊,这拖延症这样看来,它也是好

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承、虚继承与虚基类

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承.虚继承与虚基类 一.多重继承 在C++语言中,一个派生类可以从一个基类派生,称为单继承:也可以从多个基类派生,称为多继承. 多重继承--一个派生类可以有多个基类 class <派生类名> : <继承方式1> <基类名1>,<继承方式2> <基类名2>,... { <派生类新定义成员> }; 可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个

快速理解JavaScript面向对象编程—原型继承

总的来说js语言就是门面向对象编程的语言,对象这个概念几乎贯穿了整个js的学习. 对象 创建对象两种方法:(若要生成对象实例必须调用构造函数) 1.var obj = {name:"jer" , age:12};(在js内部调用了预设的Object()构造函数) 访问:alert(obj.name);//"jer" alert(obj["name"]);//"jer" 2.var obj = new Object(); obj

JavaScript面向对象之类的继承

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

C++构造函数 &amp; 拷贝构造函数 &amp; 派生类的构造函数 &amp; 虚继承的构造函数

构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载.(摘自百度百科构造函数). 一.最基本的构造函数 1 class Base 2 { 3 public: 4 Base(int var) : m_Var(var) 5 { 6 } 7 private: 8 int m_Var; 9 }; 以上构造函数的执行过程: