Learning PHP-面向对象的PHP

面向对象的开发方法试图在系统中引入对象的分类、关系和属性,从而有助于程序开发和代码重用。
面向对象软件 由一系列具有属性和操作的自包含对象组成,这些对象之间能够交互,从而达到我们的要求。
  • 封装
  • 多态
  • 继承

创建类(class)
class classname{
     
     public $attribute1;
     public $attribute2;
     
     function operation1()
     {
     }
     function operation2($param1, $param2)
     {
     }
}

构造函数
大多数类都有一种称为构造函数的特殊操作。当创建一个对象时,它将调用构造函数,通常,这将执行一些有用的初始化任务:例如,设置属性的初始值或者创建该对象需要的其他对象。
构造函数的声明与其他操作的声明一样,只是其名称必须是 __construct()
尽管可以手工调用构造函数,但其本意是在创建一个对象时自动调用。
class classname
{
     function __construct($param)
     {
          echo "Constructor called with parameter".$param."<br />";
     }
}

析构函数
与构造函数相对的就是析构函数。析构函数允许在销毁一个类之前执行一些操作或完成一些功能,这些操作或功能通常在所有对该类的引用都被重置或超出作用域时自动发生。
与构造函数的名称类似,一个类的析构函数名称必须是 __destruct().析构函数不能带任何册参数。
类的实例化
可以使用关键词" new"来创建一个对象。
使用类的属性
在一个类中,可以访问一个特殊的指针—— $this.
如果当前类的一个属性为$attribute, 则当在该类中通过一个操作设置或访问该变量时,可以使用 $this->attribute来引用。
class classname
{
     public $attribute;
     function operation($param)
     {
          $this->attribute = $param;
          echo $this->attribute;     
     }
}

通常,从类的外部直接访问类的属性是槽糕的想法。面向对象方法的一个有点是鼓励使用封装。
可以通过使用 __get()和__set()函数来实现对属性的访问。
class classname
{
     public $attribute;
     function __get($name)
     {
          return $this->$name;
     }
     function __set($name, $value)
     {
          $this->$name = $value;
     }
}

使用private和public关键字控制访问
PHP支持如下3中访问修饰符:
  • 默认选项是public,这意味着如果没有为一个属性或方法指定访问修饰符,它将是public。公有的属性或方法可以在类的内部和外部进行访问。
  • private访问修饰符意味着被标记的属性或方法只能在类的内部进行访问。私有的属性和方法将不会被继承。
  • protected访问修饰符意味着被标记的属性或方法只能在类内部进行访问。它也存在于任何子类。

在PHP中实现继承
如果类是另一个类的子类,可以用关键词" extends"来指明其继承关系。
class B extends A
{
     public $attribute2;
     function operation2()
     {
     }
}

class A
{
     public $attribute1;
     function operation1()
     {
     }  
}

通过继承使用private和protected访问修饰符控制可见性
引用
可以使用使用private和protected访问修饰符控制需要继承的内容。如果一个属性或方法被指定为private,它将不会被继承。如果一个属性或方法被指定为protected,它将在类外部不可见,但是可以被继承。

重载
我们可能需要在子类中给某个属性赋予一个与其超类属性不同的默认值,或者给某个操作赋予一个与其超类操作不同的功能。这就叫重载。
使用final关键字禁止继承和重载
当一个函数声明前面使用这个关键字时,这个函数将不能在任何子类中被重载。
也可以使用final来禁止一个类被继承。
理解多重继承
PHP并不支持多重继承
实现接口
如果需要实现多重继承功能,可以通过接口。
理解PHP面向对象的高级功能
使用 Per-Class常量
PHP提供了Per-Class常量的思想。这个常量可以在不需要初始化该类的情况下使用,如下所示:
<?php
class Math{
     const pi = 3.14159;
}
echo "Math::pi = ".Math::pi."\n";
?>

实现静态方法
PHP允许使用 static关键字。该关键字适用于允许在未初始化类的情况下就可以调用的方法。
class Math
{
     static function squared($input)
     {
          return $input*$input;
     }
}
echo Math::squared(8);

请注意,在一个静态方法中,不能使用this关键字。因为可能会没有可以引用的对象实例
检查类的类型和类型提示
instanceof关键字允许检查一个对象的类型。可以检查一个对象是否是特定类的实例,是否是从某个类继承过来或者是否实现了某个接口。
延迟静态绑定(late static binding)
该特性允许在一个静态继承的上下文中对一个被调用类的引用。父类可以使用子类重载的静态方法。
<?php
class A {
     public static function who(){
          echo __CLASS__;
     }
     public static function test(){
          static::who(); //Here comes Late Static Bindings
     }
}

class B extends A {
     public static function who(){
          echo __CLASS__;
     }
}

B::test();
?>

输出B;
克隆对象
PHP提供了 clone关键字,该关键字允许复制一个已有的对象。例如:
$c = clone $b;
将创建与对象$b具有想同类的副本,而且具有相同的属性值。
使用抽象类
PHP还提供了抽象类,这些类不能被实例化,同样类方法也没有没有实现,只是提供类方法的声明,没有具体实现。
abstract operationX($param1, $param2);

包含抽象方法的任何类自身必须是抽象的,如下例所示:
abstract class A
{
     abstract function operationX($param1, $params);
}

引用
抽象方法和抽象类主要用于复杂的类层次关系中,该层次关系需要确保每一个子类都包含并重载了某些特定的方法,这也可以通过接口来实现。

使用__call()重载方法
该方法用来实现方法的重载
方法的重载在许多面向对象变成语言中都是常见的,但是在PHP中却不是非常有用,因为我们习惯使用灵活的类型和可选的函数参数。
要使用该方法,必须实现 __call()方法,如下例所示:
public function __call($method, $p)
{
     if($method == 'display'){
          if(is_object($p[0])){
               $this->displayObject($p[0]);     
          }else if(is_array($p[0])){
               $this->displayArray($p[0]);
          }else{
               $this->displayScalar($p[0])'
          }
     }
}

__call()方法必须带有两个参数。第一个包含了被调用的方法名称,而第二个参数包含了传递该方法的参数数组。
使用__autoload()方法
可以在任何类声明之外声明这个函数。如果实现了这个函数,它将在实例化一个还没有被声明的类时自动调用。
__autoload()方法的主要用途是尝试包含或请求任何用来初始化所需类的文件
function __autoload($name)
{
     include_once $name.".php";
}

该代码实现将包括一个具有与该类相同名称的文件。
实现迭代器和迭代
可以使用foreach()方法通过循环方式出去一个对象的所有属性。
引用
如果需要一些更加复杂的行为,可以实现一个iterator。要实现一个迭代器,必须将要迭代的类实现IteraotrAggregate接口,并且顶一个一个更够返回该迭代类实例的getIterator方法。这个类必须实现Iterator接口,该接口提供了一系列必须实现的方法。

<?php
class ObjectIterator implements Iterator{
private $obj;
private $count;
private $currentIndex;

function __construct($obj)
{
     $this->obj = $obj;
     $this->count = count($this->obj->data);
}

public function current() {
     return $this->obj->data[$this->currentIndex];
}

public function next() {
     $this->currentIndex++;
}

public function key() {
     return $this->currentIndex;
}

public function valid() {
     $this->currentIndex < $this->count;
}

public function rewind() {
     $this->currentIndex = 0;
}
}

class Object implements IteratorAggregate{
public $data = array();

function __construct($in){
     $this->data = $in;
}
/* (non-PHPdoc)

* @see IteratorAggregate::getIterator()

*/

public function getIterator() {
     return new ObjectIterator($this);
}
}

$myObject = new Object(array(2,4,6,8,10));
$myIterator = $myObject->getIterator();
for ($myIterator->rewind();$myIterator->valid();$myIterator->next())
{
     $key = $myIterator->key();
     $value = $myIterator->current();
     echo $key." => ".$value."<br />";
}

?>

ObjectIterator类具有Iterator接口所要求的一些列函数:
  • 构造函数并不是必须的,但是很明显,它是设置将要迭代的项数和当前数据项链接的地方。
  • rewind()函数将内部数据指针设置回数据开始处。
  • valid()函数将判断数据指针的当前位置是否还存在更多数据。
  • key()函数将返回数据指针的值。
  • value()函数将返回保存在当前数据指针的值。
  • next()函数在数据中移动数据指针的位置。

将类转换成字符串
如果在类定义中实现了__toString()函数,当尝试打印该类时,可以调用跟这个函数。
使用Reflection(反射)API
PHP面向对象引擎还包括反射API。反射是通过访问已有类和对象来找到类和对象的结构和内容的能力。
<?php
require_once("page.inc");
$class = new ReflectionClass("Page");
echo "<pre>".$class."</pre>";
?>


参考资料:
PHP&MySQL.Web

你可能感兴趣的:(PHP)