PHP面对对象编程

PHP面向对象编程

类的声明

[修饰关键字]class 类名{

​ 类中成员【成员属性,成员方法】;

}

成员属性

类中直接申明的变量就称为成员属性。

class Person{
    public $name;//声明为公有权限
    privite $age;//声明为私有权限
    static $sex;//声明为静态权限
    var $weight;//不需要有特定意义的修饰
}

成员方法

class Person{
    function say(){//声明第一个成员方法,定义人说话的功能
        //方法体
    }
    function eat($food){//声明第二个成员方法,定义人吃饭的功能
        //方法体
    }
    private function run(){//定义人可以走路的功能,使用private修饰控制访问的权限
        //方法体
    }
}

通过类实例化对象

对象实例化格式

$变量名=new 类名称([参数列表]);
$变量名=new 类名称; //不需要传入参数

对象类型在内存中的分配

栈空间段:存储占用空间不变并且占用空间小的数据类型内存段

堆空间段:进程运行中被动态分配的内存段,大小不固定。

初始化数据段:存放已初始化的全局变量

代码段:存放可执行文件的操作指令

对象中成员的访问

$引用名=new 类名称(【参数列表】);
$引用名->成员属性=值;
echo $引用名->成员属性;
$引用名->成员方法

特殊的对象引用"$this"

$this专门用来完成对象内部成员之间的访问。在对象内部的成员方法中,代表"本对象"的一个引用。

<?php
    class Person{
        var $name;
        var $sex;
        var $age;
    
        function say(){
            echo "我的名字:".$this->name.", 性别:".$this->sex.",年龄:".$this->age."。<br>
        }
        function run(){
            echo $this->name."在走路.<br>";
        }
    }
    $person1=new Person();
    $person2=new Person();
    $person3=new Person();
    
    $person2->name="李四";//给$person2对象中的属性初始化赋值
    $person2->sex="女";
    $person2->age=30;
    

构造方法与析构方法

构造方法是对象创建完成后第一个被对象自动调用的方法。析构方法是对象在销毁之前最后一个被对象自动调用的方法。

类中声明构造方法的格式:

function __construct([参数列表]){//构造方法名称是以两个下划线开始

​ //方法体,通常用来对成员属性进行初始化赋值

}

<?php
    //声明类Person,其中声明一个构造方法
    class Person{
        var $name;
        var $sex;
        var $age;
        //声明构造方法,创建对象时为对象成员赋初值,设置默认值
        functon __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
        function run(){
            echo $this->name."在走路<br>";
        }
    }
    //实例化三个对象,并使用构造方法分别为新创建的对象成员属性赋予初值
    $person1=new Person("张三","男",20);
    $person2=new Person("李四","女");
    $person3=new Person("王五");
    $person->say();
    $person->say();
    $person->say();

析构方法

声明格式

function __destruct(){
    //方法体,通常用于完成对象销毁前的清理任务
}
<?php
    class Person{
        var $name;
        var $sex;
        var $age;
        function __construct($name,$sex,$age){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this-sex.",年龄:".$this->age."。<br>";
        }
        function run(){
            echo $this->name."在路上<br>";
        }
        //声明析构方法,在对象销毁前自动调用
        function __destruct(){
            echo "再见".$this->name."<br>";
        }
    }
    $person1=new Person("张三","男",20);
    $person1=null;//结束引用输入张三
    $person2=new Person("李四","女",30);
    $person3=new Person("王五","男",40);

封装性

设置私有成员

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        //在类中声明一个走路方法,调用两个内部的私有方法
        function run(){
            echo $this->name."在走路时".$this->leftleg()."再".$this->rightleg()."<br>";
        }
        //声明一个迈左腿的方法,被封装只能内部使用
        private function leftleg(){
            return "迈左腿";
        }
        //声明一个迈右腿的方法,被封装只能在内部使用
        private function rightleg(){
            return "迈右腿";
        }
    }
    $person1=new Person();
    $person1->run();//run()方法未被封装,可以在对象外部使用
    $person1->name="李四";//name属性被封装,不能在外部给私有属性赋值
    echo $person1->age;//age属性被封装,不能在外部给私有属性赋值
    $person->leftleg();//被封装,不能在对象外面调用私有方法

私有成员的访问

通过对象内部的公有方法访问私有成员

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        //通过这个公有方法在对象外部获取私有属性$name的值
        public function getName(){
            return $this->name;
        }
        public function setSex($sex){
            if($sex=="男"||$sex=="女")
                $this->sex=$sex;//为私有属性赋值
        }
        public function setAge($age){
            if($age>150||$age<0)
                return;
            $this->age=$age;
        }
        //在对象外部获取私有属性$name的值
        public function getAge(){
            if($this->age>30)
                return $this->age-10;
            else
                return $this->age;
        }
        //声明人的成员公有方法,说出自己所有的私有属性
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
    }
    $person1=new Person("王五","男",40);
    echo $person1->getName()."<br>";
    $person1->setSex("女");
    $person1->setAge(200);
    echo $person1->getAge()."<br>";
    $person->say();
    

__set(),__get(),__isset()和__unset()

__set(),__get()对私有属性获取和赋值的操作,__isset()检查私有属性是否存在的方法__unset()删除对象中私有属性的方法。

魔术方法__set()

void __set(string name,mixed value)//以两个下画线开始的方法名,方法体的内容需要自定义

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        //声明魔术方法需要两个参数,为私有属性赋值时自动调用,并且屏蔽一些非法赋值
        private function __set($propertyName,$propertyValue){
            if($propertyName=="sex"){
                if(!$propertyValue=="男"||$propertyValue=="女")
                return;
            }
            if($propertyName=="age"){
                if($propertyValue>150||$propertyValue<0)
                    return;
            }
            $this->$propertyName=$propertyValue;
        }
        public function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
    }
    $person1->name="李四";
    $person1->sex="女";
    $person1->age=80;
    $person1->sex="保密";
    $person1->age=800;
    $person1->say();

魔术方法__get()

类中声明了该方法,直接在对象的外部获取私有属性的值时,会自动调用此方法。返回私有属性的值

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        private function __get($propertyName){
            if($propertyName=="sex"){
                return "保密";
            }else if($propertyName=="age"){
                if($this->age>30){
                    return $this->age-10;
                }else{
                    return $this->$propertyName;
                }
            }else{
                return $this->$propertyName;
            }
        }
    }
    $person1=new Person("张三","男",40);
    echo "姓名:".$person1->name."<br>";
    echo "性别:".$person1->sex."<br>";
    echo "年龄:".$person1->age."<br>";

魔术方法__isset()和__unset()

使用格式
bool __isset(string name)//测量对象的成员属性是否存在
void __unset(string)//将私有属性删除
<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        private function __isset($propertyName){
            if($propertyName=="name")
                return false;
            return isset($this->$propertyName);
        }
        private function __unset($propertyName){
            if($propertyName=="name")
                return;
            unset($this->$propertyName);
        }
        public function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
    }
    $person1=new Person("张三","男",40);
    var_dunp(isset($person1->name));//返回false不允许测定name
    var_dump(isset($person1->sex));//返回true
    var_dump(isset($person1->id));//不存在id属性
    unset($person1->sex);//删除对象中私有属性sex

继承性

指从一个先前定义的类中继承和重新定义并且可以加进新数据和函数从而建立一个新的派生类,从而建立类的层次或等级关系。php中采用单继承,一个子类只允许有一个父类,一个父类可以有多个子类。

<?php
    class Person{
        var $name;
        var $sex;
        var $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say{
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
        function run(){
            echo $this->name."正在走路。<br>";
        }
    }
    class Student extends Person{
        var $school;
        function study(){
            echo $this->name."正在".$this->school."学习<br>";
        }
    }
    class Teacher extends Student{
        var $wage;
        function teaching(){
            echo $this->name."正在".$this->school."教学,每月工资为".$this->wage."。<br>";
        }
    }
    $teacher1=new Teacher("张三","男",400);
    $teacher->school="edu";
    $teacher->wage=3000;
    $teacher->say();
    $teacher->study();
    $teacher->teaching();

访问类型控制

private:同一个类中允许访问

protected:同一个类中,类的子类中允许访问

public:所有成员

子类中重载父类的方法

在子类中定义一个和它父类同名的方法,将其覆盖后重写

<?php
    class Person{
        protected $name;
        protected $sex;
        protected $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄".$this->age."。<br>";
        }
    }
    class Student extends Person{
        private $school;
        function __construct($name="",$sex="男",$age=1,$school=""){//覆盖父类中的构造方法
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
            $this->school=$school;
        }
        function study(){
            echo $this->name."正在".$this->school."学习<br>";
        }
        function say(){//定义一个和父类同名的方法,将父类说话方式重写并覆盖
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age.",在".$this->school."学校上学<br>";
        }
    }
//在子类中调用重载
<?php
    class Person{
        protected $name;
        protected $sex;
        protected $age;
        function __construct($name="",$sex="男",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."。<br>";
        }
    }
    class Student extends Person{
        private $school;
        function __construct($name="",$sex=男,$age=1,$school=""){
            parent::__construct($name,$sex,$age);//为从父类继承过来的子类赋初值
            $this->school=$school
        }
        function study(){
            echo $this->name."正在".$this->school."学习<br>";
        }
        function say(){
            parrent::say();
            echo "在".$this->school."学校上学<br>";
        }
    }
    $student=new Student("张三","男",20,"edu");
    $student->say();

常见的关键字和魔术方法

final关键字的应用

使用final标识的类不能被继承,在类中使用final标识的成员方法,在子类中不能被覆盖

<?php
    final class MyClass{//声明一个类,并使用final关键字标识
        //
    }
    class MyClass2 extends MyClass{//声明继承MyClass类的子类,结果出错
        //
    }

 

<?php
    class MyClass{
        final function fun(){//声明一个成员方法,使其不能被子类覆盖
            //
        }
    }
    class MyClass2 extends MyClass{
        function fun{//无法覆盖,出错
            //
        }
    }

static关键字的使用

static标识的成员是属于类的,在其声明中的每一个对象值均通用

访问方式

类名::静态成员属性名;//在类的外部和成员方法中都可以使用这种方式访问静态成员属性

类名::静态成员方法名();//在类的外部和成员方法中都可以使用这种方式访问静态成员方法

在类中声明的成员方法中,使用“self”来访问其他静态成员

self::静态成员属性名;

self::静态成员方法名();

类外部通常使用类名来访问,在类内部成员方法中通常使用self形式访问

<?php
    class MyClass{
        static $count;
        function __construct(){
            self::$count++;//使用self访问静态成员,使其自增
        }
        static function getCount(){//声明一个静态成员方法,在类外直接使用类名进行调用
            return self::$count;//在方法中使用self调用并返回静态成员
        }
    }
    MyClass::$count=0;//类外面使用类名访问类中的静态成员
    $myc1=new MyClass();
    $myc3=new MyClass();
    echo MyClass::getCount();//类外面使用类名访问类中的静态成员方法
    echo $myc3->getCount();

单态设计模式

保证在面对对象编程中,一个类只能有一个实例存在。

<?php//声明一个DB,用于演示单态模式的使用
    class DB{
        private static $obj=null;
        private function __construct(){//构造方法使用private封装后则只能在类的内部使用new去创建对象
            echo "连接数据库成功<br>";
        }
        //只有通过这个方法才能返回本类对象
        static function getInstance(){
            if(is_null(self::$obj))//如果$obj为空,则说明没有实例化过
                self::$obj=new self();//实例化本类对象
            return self::$obj;
        }
        function query($sql)(
            echo $sql;
        )
    }
    $db=DB::getInstance();
    $db->query("select * from user");

const关键字

在类中定义一个值不能改变的常量

<?php
    class MyClass{
        const CONSTANT='CONSTANT value';//使用const声明一个常量
        function showConstant(){
            echo self::CONSTANT."<br>";//使用self访问常量
        }
    }
    echo MyClass::CONSTANT."<br>";//使用类名称访问常量
    $class=new MyClass();
    $class->showConstant();//调用对象方法访问常量
    

instanceof关键字

使用instanceof关键字确定一个对象是类的实例,子类还是某个特定接口,并进行相应操作。

$man=new Person();
if($man instanceof Person)
    echo '$man是Person类的实例对象';

克隆对象

为对象建立一个完全独立,互不干扰的副本,使用clone

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="",$age=1){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄".$this->age."<br>";
        }
    }
    $p1=new Person("张三","男",20);
    $p2=clone $p1;//使用clone关键字克隆对象,创建一个对象副本
    $p1->say();
    $p2->say();

重新赋值则需要在类中声明魔法方法__clone

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="",$age=""){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function __clone(){//在克隆对象时自动调用,为新对象重新赋值
            $this->name="我是".$this->name."的副本";
            $this->age=10;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."<br>";
        }
    }
    $p1=new Person("张三","男",20);
    $p2=clone $p1;
    $p1->say();
    $p2->say();

类中通用方法__toString()

直接输出对象引用时自动调用的方法,是快速获取对象的字符串表示的最便捷的方式。

<?php
    class TestClass{
        private $foo;
        function __construct($foo){
            $this->foo=$foo;
        }
        public function __toString(){//定义一个__toString方法
            return $this->foo;//返回一个成员属性$foo的值
        }
    }
    $obj=new TestClass('Hello');
    echo $obj;//直接输出对象引用则自动调用了对象中的__toString()方法输出Hello

__call()方法的应用

当调用对象不存在时,自动调用该方法

<?php
    class TestClass{
        function printHello(){
            echo "Hello<br>";
        }
        function __call($functionName,$arge){
            echo "你所调用的函数:".$functionName."(参数:";//输出调用不存在时的方法名
            print_r($args);//输出调用不存在的参数列表
            echo ")不存在<br>\n";
        }
    }
    $obj=new TestClass();
    $obj->myFun("one",2,"three");
    $obj->otherFun(8,9);
    $obj->printHello();
<?php
    class DB{
        private $sql=array(
            "field"=>"",
            "where"=>"",
            "order"=>"",
            "limit"=>"",
            "group"=>"",
            "having"=>""
        );
        function __call($methodName,$args){
            $methodName=strtolwer($methodName);
            if(array_key_exists($methodName,$this->sql)){
                $this->sql[$methodName]=$args[0];
            }else{
                echo '调用类'.get_class($this).'中的方法'.$methodName.'()不存在';
            }
            return $this;
        }
        function select(){
            echo "SELECT FROM {$this->sql['filed']} user {$this->sql['where']}{$this->sql['order']}{$this->sql['limit']}{$this->sql['group']}{$this->sql['having']}";
        }
    }
    $db=new DB;
    $db->filed('sex,count(sex)')
       ->where('where sex in ("男","女")')
       ->group('group by sex')
       ->having('having avg(age)>25')
       ->select();
    $db->query('select * from user');

自动加载类

当使用一个PHP没有组织到的类时,会寻找名为__autoload()的全局函数

<?php
    function __autoload($className){//在方法中使用include包含类所在的文件
        include(strtolower($className).".class.php");
    }
    $obj=new User();//User类不存在则自动调用__autoload()函数,将"User"作为参数传入
    $obj2=new shop();

对象串行化

对象通过写出描述自己状态的数值来记录自己,这个过程称为对象的串行化,也就是把整个对象转换为二进制字符串。

应用场景1,对象需要在网络中传输,2.对象需要持久保存时,将对象串行化后写入文件或数据库中。

串行化函数serialize(),反串行化函数unserialize(),

//脚本文件person.class.php
<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="",$age=""){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字:".$this->name.",性别:".$this->sex.",年龄:".$this->age."<br>";
        }
    }
//serialize.php函数
<?php
    require "person.class.php";//本文件中包含Person类所在的脚本
    $person=new Person("张三","男",20);
    $person_string=serialize($person);//通过serialize()函数将对象串行化,返回一个字符串
    file_put_contents("file.txt",$person_string);//将对象串行化后返回的字符串保存到file.txt文件中
//创建unserialize.php脚本文件反串行化对象
<?php
    require "person.class.php";//包含Person类所在的脚本
    $person_string=file_get_contents("file.txt");//将file.txt文件中的字符串读出来并赋值给变量$person_string
    $person=unserialize($person_string);//进行反串行化操作,生成对象$person
    $person->say();//调用对象中say()方法,用来测试反串行化对象是否成功

__sleep()方法将对象中的部分成员串行化,

__wakeup()方法,用来将二进制串重新组成一个对象。

<?php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="",$age=""){
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }
        function say(){
            echo "我的名字".$this->name.",性别:".$this->sex.",年龄:".$this->age."<br>";
        }
        //在类中添加此方法,在串行化时自动调用并返回数组
        function __sleep(){
            $arr=array("name","age");//串行化了数组中的$name,$age
            return($arr);
        }
        function __wakeup(){//反串行化时重新赋值
            $this->age=40;
        }
    }
    $person1=new Person("张三","男",20);
    $person_string=serialize($person);
    echo $person_string."<br>";
    $person2=unserialize($person_string);
    $person2->say();
    

抽象类与接口

抽象方法是没有方法体的方法。格式如下

abstract function fun1();//不能有花括号,更不能有方法体中的内容

abstract function fun2();//直接在方法名的括号后面加上分号结束

<?php
    abstract class Person{
        protected $name;
        protected $name;
        function __construct($name="",$country="china"){
            $this->name=$name;
            $this->country=$country;
        }
        abstract function say();
        abstract function eat();
        function run(){
            echo "使用两条腿走路<br>";
        }
    }

抽象类不完整,相当于定义了一个规范,再通过定义子类来实现它的抽象方法等

<?php
    class ChineseMan ectends Person{//声明一个类去继承Person
        function say(){//将父类中的抽象方法覆盖掉
            echo $this->name."是".$this->country."人,讲汉语<br>";
        }
        function eat(){
            echo $this->name."使用筷子吃饭<br>";
        }
    }
    class Americans extends Person{
        function say(){
            echo $this->name."是".$this->country."人,讲英语<br>";
        }
        function eat(){
            echo $this->name."使用刀子和叉子吃饭<br>";
        }
    }
    $chineseMan=new ChineseMan("洛峰","中国");
    $americans=new Americans("alex","美国");
    $chineseMan->say();
    $chineseMan->eat();
    $americans->say();
    $americans->eat();

接口技术

接口声明的所有方法默认必须都是抽象方法,不能声明变量,只能使用const关键字声明为常量的成员属性。所有成员默认必须为public访问权限,声明时使用interface。

interface 接口名称{
    //常量成员
    //抽象方法
}
<?php
    interface one{
        const CONSTANT='CONSTANT value';
        function fun1();
        function fun2();
    }
//使用extends关键字让一个接口继承另一个接口
<?php
    interface Two extends one{
        function fun3();
        function fun4();
    }
<?php
//声明一个接口,使用interface关键字,one为接口名称
    interface one{
        const CONSTANT='CONSTANT value';
        function fun1;
        function fun2;
    }
    //使用abstract声明一个抽象类去实现接口one中的第二个方法
    abstract class Three implements one{
        function fun2(){
            //实现内容
        }
    }
    class Four implements one{声明一个类继承接口需要使用implement关键字来实现。
        function fun1(){
            //实现内容
        }
        function fun2(){
            //实现内容
        }
    }
class 类名 implements 接口一,接口二,,,,接口n{//一个类中实现多个接口
    //实现所有接口中的抽象方法
}
//继承一个类时实现多个接口
class 类名 extends 父类名 implements 接口一,接口二,‘’‘’,接口n{
    //实现所有接口中的抽象方法
}

多态性的应用

多态让具有继承关系的不同类对象,可以对相同名称的成员函数进行调用,产生不同的反应效果。多态性是指一段程序能够处理多种类型对象的能力。

<?php
    interface USB{//定义一个usb接口
        function run();
    }
    class Computer{//声明一个计算机类,去使用usb设备
        function useUSB($usb){//计算机类中的一个方法可以使用任何一个usb设备
            $usb->run();
        }
    }
    $computer=new Computer;
    $computer->useUSB(new Uker());
    $computer->useUSB(new Umouse());
    $computer->use(new Ustore());
<?php//扩展一个usb键盘设备,实现usb接口
    class Ukey implements USB{
        function run(){
            echo "键盘";
        }
    }
    class Umouse implements USB{
        function run(){
            echo "鼠标";
        }
    }
    class Useore implements USB{
        function run(){
            echo "存储设备";
        }
    }

PHP5.4的Trait特性

解决同时继承两个抽象类的问题

Trait的声明

<?php
    trait DemoTrait{
        public $property1=true;
        static $property2=1;
        function method1(){//方法}
        abstract public function method2();//加入抽象修饰符,说明调用类必须实现它
    }

Trait的基本用法

trait不能靠自身来实例化对象,必须混入类中使用

<?php
    trait Demo1_trait{//声明一个简单的Trait,有两个成员方法
        function method(){
            //code
        }
        function method2(){
            //code
        }
    }
    class Demo1_class{/声明一个普通类,在类中混入Trait
        use Demo1_trait;//使用use关键字在类中使用Demo1_trait
    }
    $obj=new Demo1_class();
    $obj->method1();通过对象直接调用混入类Demo1_trait中的成员方法
    $obj->method2();
class Demo1_class{
    //混入多个Trait
    use Demol_trait,Demo2_trait,Demo3_trait;
}
<?php
    trait Demo1_trait{
        function func{
            echo "方法";
        }
    }
    trait Demo2_trait{
        function func(){
            echo "方法"
        }
    }
    class Demo_class{
        use Demol_trait,Demo2_trait{
            Demo1_trait::func insteadof Demo2_trait;//声明使用Demo1_trait的func替换
        }
    }
    $obj=new Demo_class();
    $obj->func();
<?php
    trait Demo1_trait{
        function method1(){
            //code
        }
    }
    trait Demo2_trait{
        use Demo1_trait;//在Trait中使用use,将Demo1_trait混入形成嵌套
        function method2(){
            //code;
        }
    }
    class Demo1_class{
        use Demo2_trait;//使用use混入Demo2_trait
    }
    $obj=new Demo1_class();
    $obj->method1();
    $obj->method2();//直接调用混入类Demo2_trait中的成员方法method2()
<?php
    trait Demo_trait{
        abstract public founction func();
    }
    class Demo_claass;{
        use Demo_trait;
        funotion func(){//实现从Trait中混入抽象方法
             //code
        }
    }
    

PHP5.3版本新增的命名空间

使用namespace关键字进行独立空间命名

<?php
    //声明该段代码的命名空间
    namespace Myproject;//写于顶部,第一个指令
    //code
//同一文件里定义不同命名空间代码
<?php
    namespace MyProject1;
    class User{
        //code
    }
    namespace MyProject2;
    class User{
        //code
    }
    namespace MyProject3{
        //code
    }
//使用命名空间语法在不同空间中调用元素
<?php
    namespace MyProject1;//定义命名空间方法
    const TEST='this is a const';//在MyProject1中声明一个常量TEST
    function demo(){
        echo "rhis is a function";
    }
    class User{
        function fun(){
            echo "this is User's fun";
        }
    }
    echo TEST;
    demo();
    
    
    namespace MyProject2;
    const TEST2="this is MyProject2 const";
    echo TEST2;
    \MyProject1\demo();//调用命名空间MyProject1中的demo()函数
    $user=new \MyProject1\User();//使用MyProject1空间的类实例化对象
    $user->fun();
    

命名空间的子空间和公共空间

<?php
    namespace broshop\cart;//使用命名空间表示处于brophp项目下的cart模块
    calss Test{}//声明Test类
    namespace brophp\order;//使用命名空间表示处于brophp项目下的order模块
    class Test{};//声明和上面空间相同的类
    $test=new Test();//调用当前空间的类
    $cart_test=new \brophp\cart\Test();//调用brophp\cart空间的类
//公共空间代码段引入命名空间
<?php
    function func(){
        //code
    }
    class Demo{
        //code
    }
<?php
    namespace cn\ydma;//声明命名空间
    include './common.inc.php';//引入当前目录下的脚本文件
    $demo=new \Demo();//调用公共空间的方式在前加\
​
    \var_dump;

命名空间中的名称和术语

非限定名称:不包含前缀的类名称如$u=new User();如果当前命名空间是cn\ydma,则会被解析成cn\ydma\User,在公共空间中则被解析成User

限定名称:包含前缀的名称如:$u=new ydma\User();如果当前命名空间是cn,则会被解析成cn\ydma\User,在公共空间中则被解析成User

完全限定名称:包含了全局前缀操作符的名称如:$u=new \ydma\User();,User被解析为ydma\User

<?php
    namespace cn;
    class User{}
    $cn_User=new User();//非限定名称
    $ydma_User=new ydma\User();//限定名称
    $ydma_User=new \cn\User();//完全限定名称
    $ydma_User=new \cn\ydma\User();//完全限定名称
    namespace cn\ydma;
    class User{}

别名和导入

<?php
    namespace cn\ydma;
    class User{}
    namespace broshop;
    use cn\ydma;//导入命名空间
    $ydma_User=new ydma\User();//使用限定名称调用元素
    use cn\ydma as u;//为命名空间使用别名
    $ydma_User=new u\User();//使用别名代替空间名
    use cn\ydma\User;//导入一个类
    $ydma_User=new User();//导入类后使用非限定名称调用元素
    use cn\ydma\User as CYUser;//为类使用别名
    $ydma_User=new CYUser();//使用别名代替空间名

使用__NAMESPACE__动态的访问元素

<?php
    namespace cn\ydma;
    const PATH='/cn/ydma';
    class User{}
    echo namespace\PATH;
    $User=new namespace\User();
    echo __NAMESPACE__;//魔法常量的值为当前空间名称
    $User_class_name=__NAMESPACE__.'\User';//组合成字符串并调用
    $User=new $User_class_name();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值