面向对象的一些概念

2017-10-12  本文已影响0人  邱杉的博客

面向接口编程

接口定义一套规范,描述一个“物”的功能,要求如果现实中的“物”想成为可用,就必须实现这些基本功能。

接口本身并不提供实现,只是提供一个规范。如果我们知道一个类实现了某个接口,那么就知道了可以调用该接口的哪些方法,我们只需要知道这些就够了。

由于PHP是弱类型,且强调灵活,所以并不推荐大规模使用接口,而是仅在部分“内核”代码中使用接口,因为PHP中的接口已经失去很多接口应该具有的语义。从语义上考虑,可以更多地使用抽象类。至于抽象类和接口的比较,不再赘述。

接口作为一种规范和契约存在。作为规范,接口应该保证可用性;作为契约,接口应该保证可控性。
PHP中的接口存在两个不足,一是没有契约限制,二是缺少足够多的内部接口。

一个子类如果implements一个接口,就必须实现接口中的所有方法(不管是否需要);如果继承一个抽象类,只需要实现需要的方法即可
如果一个接口中定义的方法名改变了,那么所有实现此接口的子类需要同步更新方法名;而抽象类中如果方法名改变了,其子类对应的方法名将不受影响,只是变成了一个新的方法而已
抽象类只能单继承,当一个子类需要实现的功能需要继承多个父类时,就必须使用接口

interface Demo
{
  public function func1();
  public function func2();
}

interface Demo2 extends Demo
{
  public function func3();
  public function func4();
} 

interface Demo3 
{
  public function func5();
  public function func6();
}

class ParentClass
{
  public function func7(){}
}


class ChildClass extends ParentClass implements Demo2, Demo3
{
  public function func1(){}
  public function func2(){}
  public function func3(){}
  public function func4(){}
  public function func5(){}
  public function func6(){}
}

反射

面向对象编程中对象被赋予了自省的能力,而这个自省的过程就是反射。
反射,直观理解就是根据到达地找到出发地和来源。

$ref = new ReflectionClass($classname)
$ref->getProperties();
$ref->getMethods();
$ref->isInstantiable();
$res->newInstanceArgs();

在平常开发中,用到反射的地方不多:一个是对对象进行调试,另一个是获取类的信息。在MVC和插件开发中,使用反射很常见,但是反射的消耗也很大,在可以找到替代方案的情况下,就不要滥用。

很多时候,善用反射能保持代码的优雅和简洁,但反射也会破坏类的封装性,因为反射可以使本不应该暴露的方法或属性被强制暴露了出来,这既是优点也是缺点。

<?php

// 厨师
class Cook
{
  public function meal()
  {
    echo 'meal <br>';
  }
  
  public function drink()
  {
    echo 'drink <br>';
  }
  
  public function ok()
  {
    echo 'ok <br>';
  }
}

// 命令接口
interface Command
{
  public function execute();
}

// 炒菜命令
class MealCommand implements Command
{
  public $cook;
  
  public function __construct($cook){
    $this->cook = $cook;
  }
  
  public function execute()
  {
    $this->cook->meal();
  }
}

// 饮料命令
class DrinkCommand implements Command
{
  public $cook;
  
  public function __construct($cook)
  {
    $this->cook = $cook;
  }
  
  public function execute()
  {
    $this->cook->drink();
  }
}

// 顾客下单
class cookController
{
  public $mealCommand;
  public $drinkCommand;
  
  public function __construct(MealCommand $mealCommand, DrinkCommand $drinkCommand)
  {
    $this->mealCommand = $mealCommand;
    $this->drinkCommand = $drinkCommand;
  }
  
  public function callMeal()
  {
    $this->mealCommand->execute();
  }
  
  public function callDrink()
  {
    $this->drinkCommand->execute();
  }
}

$cook = new Cook();
$mealCommand = new MealCommand($cook);
$drinkCommand = new DrinkCommand($cook);

$c = new cookController($mealCommand, $drinkCommand);
$c->callMeal();
$c->callDrink();
上一篇下一篇

猜你喜欢

热点阅读