PHP 13: 类

原文:PHP 13: 类
Notice: This article is working on progress!

本章将介绍PHP类.
现在,基本上每种语言都支持面向对象,当然PHP也不列外。
PHP在以前的版本不支持面向对象,但自从PHP4,包括PHP4之后开始支持了。本系列将以PHP5为例来描述面向对象的知识。在后面也将提及PHP4的知识。
PHP对面向对象的支持的能力,以我个人观点,没有C++,C#,Java等语言那么深入,即使如此,也算得上是比较全面的。
你问问现在的每一个人面向对象的特点是什么?他们肯定回答封装,多态,继承,没错,就是这些。


好了,我们从类开始说起吧。类的概念不说了,世人都知道。
PHP中的类可以这样写:

<?php
 class Page
 {
     
 }
?>

它定义了一个简单的类Page,什么都没有。
你也可以定义属性和方法,如下:

<?php
 class Page
 {
     //2 attributes
      var $attribute1;
      var $attribute2;
      
      //2 functions
      function Operation1()
      {
      }
      
      function Operation2($param1,$param2)
      {
      }
 }
?>

PHP的类有构造和析构函数吗?答案是肯定的,有!那么是不是和C++的一样呢?不是,它有专门的函数。
构造用__construct();析构用__destruct();(注意:前面是2个下划线)
代码如下:

 1 <?php
 2  class Page
 3  {
 4      //2 attributes
 5       var $attribute1;
 6       var $attribute2;
 7       
 8       //2 functions
 9       function Operation1()
10       {
11       }
12       
13       function Operation2($param1,$param2)
14       {
15       }
16       
17       //construction function
18       function __construct($param)
19       {
20            $this->attribute1=$param;
21       }
22       
23       //destruction function
24       function __destruct()
25       {
26            $this->attribute1=0;
27       }
28  }
29 ?>

PHP支持重载吗?是的,PHP支持重载,这样就可以有多种方式进行构造了。
类的实例化
构建了类,我们就需要应用它,如何使用?实例化,这个和其他语言一样,所以只给出代码:

 1 <?php
 2  class Page
 3  {
 4      //2 attributes
 5       var $attribute1;
 6       var $attribute2;
 7       
 8       //2 functions
 9       function Operation1()
10       {
11       }
12       
13       function Operation2($param1,$param2)
14       {
15       }
16       
17       //construction function
18       function __construct($param)
19       {
20            $this->attribute1=$param;
21            echo "It will construct the attribute: {$this->attribute1}<br>";
22       }
23       
24       //destruction function
25       function __destruct()
26       {
27            $this->attribute1=0;
28       }
29  }
30  $instance1=new Page("attribute1 in instance 1");
31  $instance2=new Page("attribute2 in instance 2");
32  $instance1=new Page();
33 ?>

输出结果是:

1 It will construct the attribute: attribute1 in instance 1
2 It will construct the attribute: attribute2 in instance 2
3 It will construct the attribute: 

设置或得到属性
这个问题很有意思。
拿上面的例子来说, $attribute1就是一个属性,我们可以利用 $this->attribute1来获取或设置其值。
但是为了更好的体现类的封装性,还是采用PHP提供的get或set方法,这个和C#里的功能这样。但是在PHP中,提供2个方法:__get($name),__set($name,$value)函数来设置属性。
这样做的另外一个好处就是根据实际需要,加入自己的逻辑,如果直接赋值的话就不能办到。比如说属性一定要是1-100之间的数,怎么办?还是采用__set吧。看看代码吧:


 1 <?php
 2  class Page
 3  {
 4      //2 attributes
 5       var $attribute1;
 6       var $attribute2;
 7       
 8       //2 functions
 9       function Operation1()
10       {
11       }
12       
13       function Operation2($param1,$param2)
14       {
15       }
16       
17       //construction function
18       function __construct($param)
19       {
20            $this->attribute1=$param;
21            echo "It will construct the attribute: {$this->attribute1}<br>";
22       }
23       
24       //destruction function
25       function __destruct()
26       {
27            $this->attribute1=0;
28       }
29       function __set($name,$value)
30       {
31           if($name==="attribute2"&&$value>=2&&attribute2<=100)
32           {
33               $this->attribute2=$value;
34           }
35       }
36       function __get($name)
37       {
38            return $this->$name;
39       }
40  }
41  $instance1=new Page("attribute1 in instance 1");
42  $instance2=new Page("attribute1 in instance 1");
43  $instance3=new Page();
44  $instance3->attribute2=99;
45  echo $instance3->attribute2;
46 ?>


类成员和方法的可视性

还是public,private以及protected。和C#的作用一样。但是需要注意的是,PHP默认的是public,而不是大多数语言默认的private。基于此,上述的例子才可以使用。还需要注意的一点是,如果使用了这3个关键字,var就省略了。看个例子吧。


 1 <?php
 2  class Page
 3  {
 4      //2 attributes
 5       public $attribute1;
 6       public $attribute2;
 7       
 8       //2 functions
 9       public function Operation1()
10       {
11       }
12       
13       public function Operation2($param1,$param2)
14       {
15       }
16       
17       //construction function
18       public function __construct($param)
19       {
20            $this->attribute1=$param;
21            echo "It will construct the attribute: {$this->attribute1}<br>";
22       }
23       
24       //destruction function
25       public function __destruct()
26       {
27            $this->attribute1=0;
28       }
29       public function __set($name,$value)
30       {
31           if($name==="attribute2"&&$value>=2&&attribute2<=100)
32           {
33               $this->attribute2=$value;
34           }
35       }
36       public function __get($name)
37       {
38            return $this->$name;
39       }
40  }
41  $instance1=new Page("attribute1 in instance 1");
42  $instance2=new Page("attribute1 in instance 1");
43  $instance3=new Page();
44  $instance3->attribute2=99;
45  echo $instance3->attribute2;
46 ?>


类的继承

类的继承和C#,Java语言一样,不支持多重继承。PHP实用extends来继承一个类,和Java有些类似。
在Java里有final这个词,PHP里也有,并且作用相似,就是为了阻止继承或重载,重写方法。
提到继承,那么PHP支持接口吗?支持。例如:

 1 <?php
 2  interface IDispose
 3  {
 4      function Dispose();
 5  } 
 6  
 7  class page extends IDispose
 8  {
 9       function Dispose()
10       {
11           //Your code here.
12       }
13  }
14 ?>

PHP新的高级功能
 1. Per-class常量
    它是在PHP5引入的。这个常理不需要再初始化。例如:


1 <?php
2 class Math
3 {
4    const pi=3.1415927;
5 }
6 echo "Math::pi='.Math::pi."\n";
7 ?>

其实和C++里的静态变量一样。
2. 静态函数
  既然说到了静态变量,当然也要说静态函数了。它和上面的思想一样,实现时需要加static关键字,好多语言都是这样的。C#,Java等。
 代码可以如下:


 1 <?php
 2  class Shape
 3 {
 4   static function SquredSize($length)
 5   {
 6     return $length*$length;
 7    }
 8  }
 9 echo "Squre:".Shape::SquredSize(10);
10 ?>

3. PHP 的类的类型检查
   你要想判断一个类是不是某个类的类型。非常简单,就是instanceof,如果你使用过java,那么你非常熟悉了,因为和Java一样。如果你是用C#的,类似于C# 里的is。
4. 克隆对象
   PHP提供一个关键字,clone,就是这个功能。我看PHP是我见到语言中克隆对象比较简单的语言之一。代码如下:

$c=clone $b

如果你想改变$c的某一特性,怎么办?这个时候你需要重写__clone方法。
5. 抽象类
   PHP也支持抽象类,并且和C#等语言非常类似。给个例子吧。
 


 1 <?php
 2  abstract class Shape
 3  {
 4      abstract protected function getSquared();
 5      abstract protected function getLineCount();
 6      public function printShapeValue()
 7      {
 8          echo "The squared size is :{$this->getSquared()}<br>";
 9          echo "And the number of lines is :{$this->getLineCount()}<br>";
10      }    
11  }
12  
13  class Rectange extends Shape
14  {
15       protected function getSquared()
16       {
17            return 12*12;
18       }
19        protected function getLineCount()
20        {
21            return 4;
22        }
23  }
24  
25  class Triangle extends Shape
26  {
27      protected function getSquared()
28       {
29            return 10*12;
30       }
31      protected function getLineCount()
32      {
33            return 3;
34      }
35  }
36  
37  $rect=new Rectange();
38  $rect->printShapeValue();
39  
40  $tri=new Triangle();
41  $tri->printShapeValue();
42  ?>

输出的结果如下:

The squared size is :144
And the number of lines is :4
The squared size is :120
And the number of lines is :3

注意抽象函数的写法,abstract关键字。以及在子类里,没有override关键字,而是直接重写。这是和C#不同的。
6. 使用__call重载
  这是我认为PHP提供的一个非常cool的功能,非常的佩服。这个方法用来监视一个对象中的其它方法。如果你试着调用一个对象中不存在的方法,__call 方法将会被自动调用。
 举个例子吧。代码如下:


 1  <?php
 2 class Caller
 3 {
 4    private $x = array(1, 2, 3);
 5 
 6    public function __call($m, $a)
 7    {
 8        print "Method $m called:\n";
 9        var_dump($a);
10        return $this->x;
11    }
12 }
13 
14 $foo = new Caller();
15 $a = $foo->test1(1, "2", 3.4, true);
16 var_dump($a);
17 ?> 

显示的结果如下:

Method test1 called: array(4) { [0]=>  int(1) [1]=>  string(1) "2" [2]=>  float(3.4) [3]=>  bool(true) } array(3) { [0]=>  int(1) [1]=>  int(2) [2]=>  int(3) }

$foo->test1这个方法在foo类里不存在的,但是定义了__call之后,就可以了。
7. 使用__autoload()方法。
   这个功能仍然很cool。很多开发者写面向象的应用程序时对对每个类的定义建立一个 PHP 源文件。一个很大的痛苦是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件列表。在 PHP 5 中,我们再也不需要这样了。 __autoload 函数就能轻松搞定,当代码视图使用未定义的类时,此方法自动调用。通过调用此函数,脚本引擎在出错失败之前就有了最后一个补救的机会来加载所需的类。但是需要注意的是 __autoload 函数抛出的异常不能被 catch 语句块捕获并导致致命错误。
一个例子:

1 <?php
2 function __autoload($class_name) {
3     require_once $class_name . '.php';
4 }

6 $obj1  = new MyClass1();
7 $obj2 = new MyClass2();
8 ?>

8,实现迭代期或迭代。
   它将迭代类的所有可见的属性以及值等
9 . 将类型转化为字符串(__toString()).
   这是一个魔术函数的应用,__toString().它有点像C#里的ToString()函数一样,但是对于类本身来说还是有区别的。如果你在PHP的类里实现了该函数,它们载打印这个类时就会调用此函数,例如:

 1 <?php
 2 class Page
 3 {
 4     public function __toString()
 5     {
 6         return  'Hello';
 7     }
 8 }
 9 $page=new Page();
10 echo $page;
11 ?> 

它将输出:

Hello

10. 反射。
    没想到PHP也支持反射的。如果你对C#的反射熟悉的话,它们我就不用说了。如果不是,请继续往下看。
反射是通过类或对象查找它包含的内容的信息的能力。当此类的文档信息不详或没有提供时,可以通过反射得到类的一些属性,方法等信息。
反射继承了Zend的一些类。具体实用请参看PHP反射的类的文档。

时间: 2025-01-01 21:50:07

PHP 13: 类的相关文章

在本市13类公共场所吸烟将被劝阻

编辑动机 今天,<天津市控制吸烟条例>将正式实施,在本市13类公共场所吸烟将被劝阻,而屡教不改的烟民将面临处罚.那么,本市被控烟的场所是否做好了准备,哪些地方是控烟的"老大难"?有关职能部门将如何深入控烟场所执法呢? 稿件统筹 邓晶龙 周白石 <天津市控制吸烟条例>中明确规定,妇幼保健机构.体育场馆.公共交通工具等均属于公共场所禁烟范围,记者昨天随机走访上述地点时发现,由于在多数人的意识中,妇幼保健中心.健身馆.公交车等地不能吸烟,因此违规吸烟的现象非常少.比如

C#语法练习(13): 类[五]

通过索引器可以方便使用类中的数组(或集合)成员: using System; class MyClass { private float[] fs = new float[3] { 1.1f, 2.2f, 3.3f }; /* 属性 */ public int Length { get { return fs.Length; } set { fs = new float[value]; } } /* 索引器 */ public float this[int n] { get { return f

品牌运作可能遭遇的13类困惑

题记:2008年金融危机肆虐,市场急速紧缩,企业倍感生存压力,不少企业更是在无奈中倒闭:2009年,危机效应还将延续,形势不容乐观.在此背景下,2008年岁末,远卓品牌机构策划总监谢付亮先生应邀亲临广东东莞,现场为企业授课解惑.本文主要基于现场咨询问答,对问答顺序略作了调整,希望能帮助企业走出品牌困惑,解放思想,与时俱进,提高企业的低成本品牌运作能力和低成本营销水平,快速走出冬天的阴霾. 一.怎样入手做品牌? 企业:关于品牌有很多说法,谢老师能否给他一个简单明了的定义,什么叫品牌?有什么用?还有

第六章 Python类(面向对象编程)

什么是面向对象编程?    面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构.Python就是这种编程语言.    面向对象程序设计中的概念主要包括:对象.类.继承.动态绑定.封装.多态性.消息传递.方法.    1)对象:类的实体,比如一个人.    2)类:一个共享相同结构和行为的对象的集合.通俗的讲就是分类,比如人是一类,动物是一类.    3)继承:类之间的关系,比如猫狗是一类,他们都有四条腿,狗继承了这个四条腿,拥有了

《UML面向对象设计基础》—第1章1.6节类

1.6 类UML面向对象设计基础回想一下在机器人软件中,通过执行Hominoid.New创建了一个对象(表示一个机器人).Hominoid(类的一个例子)作为创建机器人对象(如句柄为602237 的对象)的模型.每当执行语句Hominoid.New时,示例一个与用Hominoid.New创建的每一个对象结构相同的对象."结构相同",指每个机器人对象与其他对象有相同的操作和变量,特别是当程序员编码写Hominoid类时的操作和变量.参见图1.13 类(class)是创建(示例)对象的模板

宝典——C/C++程序设计

1 计算转化为二进制后包含1的数量 int fun(int n) { int count = 0; while(n) { count++; n &= n-1; } return count; } 2 判断是否为2N !(x&(x-1)) 3 求均值 int fun(int x, int y) { return (x & y) + ((x ^ y) >> 1); } 4 求最大值 int fun(int a, int b) { return ((a+b) + abs(a-

API Hook基本原理和实现

hook是什么? windows系统下的编程,消息message的传递是贯穿其始终的.这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故事片中的"长江长江,我是黄河"一个含义.windows中定义的消息给初学者的印象似乎是"不计其数"的,常见的一部分消息在winuser.h头文件中定义.hook与消息有着非常密切的联系,它的中文含义是"钩子",这样理解起来我们不难得出"hook是消息处理中的一个环节,用于监控消息在系统中

九种常用输入法特殊符号功能揭密

平时经常要输入一些像"★"."√"之类的特殊符号,或是"壹万贰仟叁佰肆拾伍元"之类的大写金额,很多朋友不知道该如何通过常用输入法快速输入,另外在使用输入法过程中,也时常会出现用五笔输入时有些字不会拆分,用拼音输入时有些字不会读音的情况,这时又该如何来快速输入这些疑难字呢?我们把大家常用的输入法汇集在一起,介绍一下如何解决这些常见的特殊输入问题.同时对于大家选择适合自己的输入法也是一个很好的参考. 小提示 很多朋友在使用输入法时,会发现一些文字明明

关于新浪微吧使用帮助大全

1.什么是微吧? 微吧是一个基于主题讨论与交流的社区.它实现了微博内容按主题聚合,优质内容的沉淀,并且提供给用户深度讨论的平台,实现了潜在热点的挖掘发酵机制. 2.如何加入/退出微吧?如何操作? 在某吧首页点击"加关注"即可加入此吧,参与吧内讨论; 退出微吧可以在微博上取消对吧主的关注. 3.怎么发帖? 点击吧名,进入某吧首页后点击上方"加关注"按钮,再点击"发新帖"即可在吧内发帖. 4.什么是话题帖?怎么发布? 话题帖聚合了带有相同#话题#的微