您的位置:首页 > 编程语言 > PHP开发

(三)PHP面向对象理论3---接口与反射

2015-07-26 22:53 746 查看
一. 接口:

1.采用一个特定接口的所有代码都知道对于那个接口会调用什么方法。接口除了可以包含方法外还能包含常量。

2.接口为抽象而生。
<?php
header("Content-type: text/html; charset=utf-8");
interface mobile{
public function run();
}

class plain implements mobile{
public function run(){
echo "我是灰机我是灰机";
}

public function fly(){
echo "飞呀飞";
}
}

class car implements mobile{
public function run(){
echo "我是汽车我是汽车\r\n";
}
}

class machine{
function demo(mobile $a){
$a->fly();
}
}

$obj = new machine();
$obj->demo(new plain());
$obj->demo(new car());
3.PHP的接口可以淡化为设计文档:

4.补充:PHP5对面向对象的特性做了增强,其中有SPL(标准PHP库)。SPL中能实现很多接口,其中最主要的是Interator接口。
<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo){
if (!$fileinfo -> isDir()){
echo $fileinfo->getFilename(),'\t',$fileinfo->getSize(),PHP_EOL;
}
}
5.traits被视为加强型的接口:
<?php
trait Hello{
public function sayHello(){
echo 'Hello';
}
}

trait World{
public function sayWorld(){
echo 'World';
}
}

class MyHelloWorld{
use Hello,World;
public function sayExclamationMark(){
echo "!";
}
}

$o = new MyHelloWorld();
$o ->sayHello();
$o ->sayWorld();
$o->sayExclamationMark();
?>
7.总结:

a.接口作为一种规范和契约的存在。做为规范,接口应该保证可用性;做为契约,接口应该保证可控性。

b.接口只是一个声明,使用了interface关键字就应该实现它

c.PHP中的接口存在两个不足,一是没有契约限制,二是缺少足够多的内部接口
二.反射:

1.反射是在PHP运行状态中,扩展分析PHP程序,导出或者提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取信息以及动态调用对象方法的功能称为反射API。
<?php
header("Content-type: text/html; charset=utf-8");

class person{
public $name;
public $gender;
public function say(){
echo $this->name,"\tis ",$this->gender,"\r\n";
}

public function __set($name,$value){
echo "Setting $name to $value \r\n";
$this->$name = $value;
}

public function __get($name){
if (!isset($this->$name)){
echo "未设置";
$this->$name = "正在为你设置默认值";
}
return $this->name;
}
}

$student = new person();
$student->name = 'Tom';
$student->gender = 'male';
$student->age = 24;

$reflect = new ReflectionObject($student);
$props = $reflect->getProperties();
foreach ($props as $prop){
print $prop->getName()."\n";
}

$m=$reflect->getMethods();
foreach($m as $prop){
print $prop->getName()."\n";
}

//使用class返回对象属性的关联数组以及更多的信息
var_dump(get_object_vars($student));
var_dump(get_class_vars(get_class($student)));
var_dump(get_class_methods(get_class($student)));
echo get_class($student);
2.使用反射API
<?php
//此代码无结果。
//实验反射类
$obj = new ReflectionClass('person');
$className = $obj->getName();
$Methods = $Properties = array();
foreach($obj ->getProperties() as $v){
$Properties[ $v->getName() ] = $v;
}

foreach($obj->getMethods() as $v){
$Methods[$v->getName()] = $v;
}

echo "class {$className} \n{\n";
is_array($Properties) && ksort($Properties);

foreach($Properties as $k=>$v){
echo "\t";
echo $v->isPublic() ? 'public' : '',$v->isPrivate() ? 'private' : '',
$v->isProtected() ? 'protected' : '',
$v->isStatic() ? 'static' : '';
echo "\t{$k}\n";
}

echo "\n";
if (is_array($Methods)) ksort($Methods);
foreach ($Methods as $k=>$v){
echo "\tfunction {$k}(){} \n";
}
echo "}\n";
3.反射的作用:

反射可以用于文档生成。因此可以用它对文件里的类进行扫描,逐个生成描述文档。
<?php
header("Content-type: text/html; charset=utf-8");

class mysql{
function connect($db){
echo "连接到数据库{db[0]}\r\n";
}
}

class sqlproxy{
private $target;
function __construct($tar){
$this->target[] = new $tar();
}

function __call($name,$args){
foreach ($this->target as $obj){
$r = new ReflectionClass($obj);
if ($method = $r->getMethod($name)){
if ($method ->isPublic() && !$method->isAbstract()){
echo "方法前拦截记录 LOG\r\n";
$method->invoke($obj,$args);
echo "方法后拦截\r\n";
}
}
}
}
}

$obj = new sqlproxy('mysql');
$obj->connect('member');
4.反射的用途:

a.对对象进行高度

b.获取类的信息

5.反射的优缺点:

反射能保持代码的优雅和简洁,但反射也会破坏类的封装性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息