PHP面向对象编程(imooc)代码合集(四)

class10 多态

多态简单说就是用不同的类去实现同一个接口的方法,以实现不同类自己的方法

<?php
date_default_timezone_set("PRC");
/**
 * 多态
 * 1. 只要某个对象实现了接口(instanceof),就可以直接在对象上调用接口的方法
 */

interface ICanEat {
   public function eat($food);
}

// Human类实现了ICanEat接口
class Human implements ICanEat { 
  // 跟Animal类的实现是不同的
  public function eat($food){
    echo "Human eating " . $food . "\n";
  }
}

// Animal类实现了ICanEat接口
class Animal implements ICanEat {
  public function eat($food){
    echo "Animal eating " . $food . "\n";
  }
}

function eat($obj){
  if($obj instanceof ICanEat){ 
    $obj->eat("FOOD"); // 不需要知道到底是Human还是Animal,直接吃就行了
  }else{
    echo "Can't eat!\n";
  }
}

$man = new Human();
$monkey = new Animal();

// 同样的代码,传入接口的不同实现类的时候,表现不同。这就是为什么成为多态的原因。
eat($man);
eat($monkey);

?>

 

class11  抽象类

抽象类是介于接口和一般类之间的一个类,它允许自身的某些方法暂时没有具体实现;但是,抽象类和接口一样,不能直接实例化为对象,必须要一个一般类去继承它,它只能作为父类被使用

<?php
date_default_timezone_set("PRC");
/**
 * 抽象类
 * 1. 抽象类允许类里面的部分方法暂时没有具体实现,这些方法我们成为抽象方法
 * 2. 一旦类里面有抽象方法,这个类就必须是抽象类
 * 3. 抽象类跟接口一样,不能直接实例化为对象
 */

// 抽象类前面以abstract关键字开始
abstract class ACanEat {
   // 没有实现的方法需要设定为抽象方法
   // 抽象方法需要在子类中实现 
   abstract public function eat($food);

   public function breath(){
      echo "Breath use the air.\n";
   }
}

// Human类实现了ICanEat接口
class Human extends ACanEat { 
  // 跟Animal类的实现是不同的
  public function eat($food){
    echo "Human eating " . $food . "\n";
  }
}

// Animal类实现了ICanEat接口
class Animal extends ACanEat {
  public function eat($food){
    echo "Animal eating " . $food . "\n";
  }
}

$man = new Human();
$man->eat("Apple");
$man->breath(); // 和Animal共用了抽象类ICanEat的breath方法
$monkey = new Animal();
$monkey->eat("Banana");
$monkey->breath();

?>

 

 

这只后给大家简单介绍一下PHP中特有的一些方法(PHP特性),他们分别是

 __tostring()--能使对象当做String直接调用
__invoke()   --能使对象被当成方法被自动调用

 

class12 

 __tostring()--能使对象当做String直接调用
__invoke()   --能使对象被当成方法被自动调用
<?php
date_default_timezone_set("PRC");
/**
 * 魔术方法1
 * 1. 当对象被当做String使用时,__tostring()会被自动调用
 * 2. 当对象被当成方法调用时,__invoke()会被自动调用
 */
class MagicTest{
  public function __tostring(){
    return "This is the Class MagicTest.\n";
  }
  public function __invoke($x){
    echo "__invoke called with parameter " . $x . "\n";
  }
}

$obj =  new MagicTest();
echo $obj;
$obj(5);  //直接在对象中传入参数5,它会被__invoke()函数接收

?>

 

class13  

  1. 当对象访问不存在的方法名称时,__call()方法会被自动调用
  2. 当对象访问不存在的静态方法名称时,__callStatic()方法会被自动调用


<?php
date_default_timezone_set("PRC");
/**
 * 魔术方法2之方法重载
 * 1. 当对象访问不存在的方法名称时,__call()方法会被自动调用
 * 2. 当对象访问不存在的静态方法名称时,__callStatic()方法会被自动调用
 */
class MagicTest{
  public function __tostring(){
    return "This is the Class MagicTest.\n";
  }
  public function __invoke($x){
    echo "__invoke called with parameter " . $x . "\n";
  }
  public function __call($name, $arguments){
    echo "Calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";
  }

  public static function __callStatic($name, $arguments){
    echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";
  }
}

$obj =  new MagicTest();
$obj->runTest("para1", "para2");
MagicTest::runTest("para3","para4");

?>

 

class14

__set()
__get()
isset()
empty()
unset()
__unset()
<?php
date_default_timezone_set("PRC");
/**
 * 魔术方法3之属性重载
 * 1. 在给不可访问属性赋值时,__set() 会被调用。
 * 2. 读取不可访问属性的值时,__get() 会被调用。
 * 3. 当对不可访问属性调用 isset() 和empty()时,__isset() 会被调用。
 * 4. 当对不可访问属性调用 unset() 时,__unset() 会被调用
 */
class MagicTest{
  public function __tostring(){
    return "This is the Class MagicTest.\n";
  }
  public function __invoke($x){
    echo "__invoke called with parameter " . $x . "\n";
  }
  public function __call($name, $arguments){
    echo "Calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";
  }
  public static function __callStatic($name, $arguments){
    echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";
  }
  // 通过这两个方法可以实现动态的对象属性
  public function __get($name){
    return "Getting the property " . $name;
  }
  public function __set($name, $value){
    echo "Setting the property " . $name . " to value ". $value. "\n";
  }

  public function __isset($name){
    echo "__isset invoked\n";
    return false;
  }

  public function __unset($name){
    echo "unsetting property " . $name;
  }
}

$obj =  new MagicTest();
echo $obj->name . "\n";
$obj->name = "Name Value";
echo '$obj->name is set? '. isset($obj->name) . "\n";
echo '$obj->name is empty?' . empty($obj->name) . "\n";
unset($obj->name);
?>

 

 

后边几个魔术方法,具体在什么时候调用呢?

我觉得是用于容错处理的。

posted @ 2015-12-05 11:57  constructora  阅读(188)  评论(0编辑  收藏  举报