php基础2(继承,接口)

1.了解PHP的继承特性

在PHP中,类继承通过extends关键字实现。

 <?php
 // Define a base Employee class
 class Employee {
  private $name;
  // Define a setter for the private $name member.
       function setName($name) {
          if ($name == "") echo "Name cannot be blank!";
          else $this->name = $name;
       }
  // Define a getter for the private $name member
       function getName() {
          return "My name is ".$this->name."<br />";
       }
    } //end Employee class
 // Define an Executive class that inherits Employee
    class Executive extends Employee {
       // Define a method unique to Employee
      function pillageCompany() {
          echo "I'm selling company assets to finance my yacht!";
       }
    } //end Executive class
 // Create a new Executive object
    $exec = new Executive();
 // Call the setName() method, defined in the Employee class
    $exec->setName("Richard");
 // Call the getName() method
    echo $exec->getName();
 // Call the pillageCompany() method
    $exec->pillageCompany();
?>

输出:My name is Richard
I'm selling company assets to finance my yacht!

因为所有员工都有姓名,所以Executive类继承了Employee类,避免了必须重新创建name成员及相应获取方法和设置方法的麻烦。

 

2.php构造函数的继承问题

构造函数的继承节省的是代码的重写,而不是方法的声明,也就是说,在父类中声明的构造函数必须再在子类中声明一次,其实,这也是一个重写的过程。

PHP的构造函数继承必须满足以下条件:

  1. 当父类有构造函数的声明时,子类也必须有声明,否则会出错。
  2. 在执行父类的构造函数时,必须在子类中引用parent关键字。

如果父类有构造函数,而且子类没有构造函数,那么在子类实例化时确实会执行父类构造函数。例如,假设Employee类有如下构造函数:

<?php
 class Fruit {
  public function __construct($name)
  {
   echo '水果'.$name.'创建了';
  }
 }
 class Apple extends Fruit {
  public function __construct($name)
  {
   parent::__construct($name);
  }
 }
 $apple = new Apple("苹果");
 // 输出 水果苹果创建了
?>

 

 

如果父类有构造函数,而且子类没有构造函数,那么在子类实例化时确实会执行父类构造函数。例如,假设Employee类有如下构造函数:

function  __construct($name){
 $this->setName($name);
}

然后实例化CEO类,获得其name成员:

$ceo= new CEO("Gonn");
echo $ceo->getName();

结果:

$ceo= new CEO("Gonn");
echo $ceo->getName();

但是,如果子类也有构造函数,那么当子类实例化时,不论父类是否有构造函数,都会执行子类自己的构造函数。例如,假设除了Employee类包含上述构造函数外,CEO类也包含如下构造函数:

function  __construct(){
    echo "CEO object created!";
}

再来实例化CEO类,以同样的方式执行getName(),这次将得到不同的输出:

CEO object created!
My name is Gonn

当遇到parent::__construct()时,PHP开始沿着父类向上搜索合适的构造函数。因为在Executive中没有找到,所以继续搜索知道Employee类,在这里找到了合适的构造函数。如果PHP在Employee类中找到构造函数,就会执行这个构造函数。如果希望既执行Employee构造函数,又执行Executive构造函数,则需要在Executive构造函数中调用parent::__construct()。

此外,还可以选择另一种方式来引用父类的构造函数。例如,假设创建新的CEO对象时,Employee和Executive的构造函数都要执行。如上述,可以在CEO的构造函数中显示地引用这些构造函数,如下:

function __construct($name){
 Employee::__constrcut($name);
 Executive::__construct();
 echo "CEO object created!";
}

3.PHP接口的介绍与实现

接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现。之所以不给出实现的细节,是因为不同的实体可能需要用不同的方式来实现公共的方法定义。

接口中不定义类成员!类成员的定义完全交给实现类来完成。

<?php interface Fruit

{     const MAX_WEIGHT = 5;   //此处不用声明,就是一个静态常量   

  function setName($name);   

  function getName();

} //实现接口

class Apple implements Fruit {  

   private $name;    

function getName() {    

     return $this->name;  

   }   

  function setName($_name) {  

       $this->name = $_name;  

   }

}

$apple = new Apple(); //创建对象

$apple->setName("苹果");

echo "创建了一个" . $apple->getName();

echo "<br />";

echo "MAX_GRADE is " . Apple::MAX_WEIGHT;   //静态常量

?>

当类通过implements关键字实现了接口后,就完成了一个契约。接口中的所有方法都必须实现,倘若实现类没有实现所有的方法,则必须声明为抽象类,否则将出现下面所示的致命错误:

 

PHP还可以实现多个接口,一个类可以实现多个接口。只要使用 ‘,’ 将多个接口链接起来就可以。

<?php 

interface Fruit

{    

const MAX_WEIGHT = 5;   //此处不用声明,就是一个静态常量    

function setName($name);

    function getName();

}

interface Food {

 function dilicious();

}

//实现接口

class Apple implements Fruit, Food {   

  private $name;   

  function getName() {    

     return $this->name;    

}    

function setName($_name) {      

   $this->name = $_name;   

  }  function dilicious() {  

       echo '好吃';   

  }

}

$apple = new Apple(); //创建对象

$apple->setName("苹果");

echo "创建了一个" . $apple->getName();

echo $apple->dilicious();

echo "<br />";

echo "MAX_WEIGHT is " . Apple::MAX_WEIGHT;   //静态常量

?>

PHP还可以继承并实现接口:

interface Fruit {

    const MAX_WEIGHT = 5;   //此处不用声明,就是一个静态常量  

   function setName($name);  

   function getName();

}

interface Food {  

function dilicious();

}

class FoodObjects {   }

//实现接口

class Apple extends FoodObjects implements Fruit, Food {    

private $name;    

function getName() {      

   return $this->name;    

}    

function setName($_name) {   

      $this->name = $_name;   

  }  

function dilicious() {  

       echo '好吃';    

}

}

 

 

 

 

 

 

 

 

posted @ 2012-09-13 18:02  hlp鹏  阅读(161)  评论(0编辑  收藏  举报