博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php.类与对象
阅读量:6242 次
发布时间:2019-06-22

本文共 7381 字,大约阅读时间需要 24 分钟。

访问控制

属性和方法的访问控制(可见标识):

public 任何地方
private 类自身
protected 类自身,自子类及自父类

this

this 可以理解为这个类的一个实例

self

self 代表类本身

__construct

实例化时就会自动执行

public function __construct() {}

__destruct

当对象对销毁时自动执行

public function __destruct(){}

类常量

定义合不可改变

const ONE = 1

const TWO = self::ONE + 1;

可以在类外部调用

Class::Two

parent

parent代表父类

public function __construct(){ parent::__construct();}

final

final class Dad(){} 加到类定义前面表示Dad类不想被继承

class Dad(){    final public function run(){}  // 加到方法声明前面,表示方法不想被子类重写}

namespace

namespace必须放在代码文件的第一行

受命名空间影响的类型:类(包括抽像类,traits)、接口、函数和常量。
当没有使用namespace关键字指定命名空间时,当前脚本是存在于全局命名空间的。用\表示。\Class1
类全在指定的命名空间去查找,没找到则抛出错误。
函数与常量,在指定命名空间查找,没找到则到全局命名空间查找,还没打到则抛错。

函数

ns1\ns2\fn()

常量

define定义的常量是全局的,不受命名空间影响。

const定义的常量受命名空间影响。

namespace ns1\ns2;const ONE = 1;echo ns1\ns2\ONE;

use

导入类

use导入命名空间下的类

use ns1\ns2\class1;

as重命名导入的类

use ns1\ns2\class1 as class2;

导入函数

use function ns1\ns2\fn as fn1;

导入常量

use const ns1\ns2\ONE;

自动加载

__autoload

function __autoload($className){ require $className . '.php';}

spl_autoload_register

传匿名函数

spl_autoload_register(function($className){ require $className . '.php'; });

传函数名

function test($className){ require $className . '.php'; }spl_autoload_register('test');

传类

class Momo{   function autoload($className)   {           require $className . '.php';   }}spl_autoload_register([new Momo, 'autoload']);

static

声明静态属性和静态方法,不经过实例化,通过类名即可调用。

class Person(){    public static $hand = '手';      public static function run()   {           echo 'running...';   }}echo Person::$hand;Person::run();

类内部调用静态属性和静态方法用self关键字

echo self::$hand; self::run();

调用父类的静态属性和静态方法用parent关键字

echo parent::$hand; parent::run();

后期静态绑定

class A{    public static function who()   {           echo 'A类的who方法';   }      public static function test1()   {           self::who();   }      public static function test2()   {           static::who();   }}class B extends A{    public static function who()    {        echo 'B类的who方法';    }}B::test1();  // test1内部用的self,调用的是自身(A类)的静态方法B::test2();  // 后期绑定。内部用static,根据后期的调用环境确定,调用的是B类的静态方法

魔术方法

__set

class Test{    private $name = '';        public function __set($var, $val)    {        //     对$val进行数据处理        $this->$var = $val;    }}$test = new Test();$test->name = 'tom';    // 赋值tom

__get

class Test{    private $name = 'jack';    public function __get($var)    {        return $this->$var;    }}$test = new Test();echo $test->name;    // jack

__isset

用于检测私有属性是否存在

class Test{    private $name = 'mary';        public function __isset($var)    {        return isset($this->$var);    }}$test = new Test();var_dump($test->name);    // 如果不设置__isset,返回false,设置后返回true

__unset

用于删除私有属性

class Test{    private $name = 'Levi';   public function __unset($var)   {           unset()   }}$test = new Test;unset($test->name);        // 会触发__unset

__call

避免调用一个不存在的方法时产生错误,当调用的方法不存在时,__call方法会自动调用

class Test{    public function __call($fn_name, $fn_arguments)    {        echo $fn_name;        print_r($fn_arguments);    }}$test = new Test();$test->go(1, 'ok');        // 自动调用`__call`方法,打印出函数名和参数数组

__callStatic

__call类似

避免调用一个不存在的静态方法

class Test{    public static function __callStatic($fn_name, $fn_arguments)    {        echo $fn_name;        print_r($fn_arguments);    }}// `__callStatic` 必须声明为静态方法Test::go(1, 'ok');

__invoke

当对象以函数的形式调用的时候,自动调用__invoke方法

class Test{    public function __invoke($args)    {        return $args;    }}$test = new Test();$test('go.....');    // 运行__invoke

__toString

当打印对象是会调用__toString方法

class Test{    public function __toString()    {        return 'Hello world!';    }}$test = new Test;echo $test;        // 输出 Hello world!

对象复制

浅拷贝

比较省内存,对象的拷贝默认是浅拷贝。

$a = new Test();$b = $a;    // 浅拷贝。传址。改变$b。$a也会改变。

对象的复制是浅拷贝的。传址。

普通变量的拷贝是深拷贝的。传值。

深拷贝

$a = new Test();$b = clone $a;    // 深拷贝。改变$b,不会改变$a。

__clone

当使用clone关键字时,自动调用__clone方法

class Test{    public $obj = null;    public function __clone()    {        $this->obj = clone $this->obj;    }}class Person{    public $sex = 0;}$a = new Test;$a->obj = new Person;$b = clone $a;        // 触发`__clone` 对obj进行深拷贝$b->obj->sex = 1;    // $b中的obj对象改变了。而$a中的obj对象没变。

类型约束

class A{    public function go()    {        echo 'go .....';    }}function test(A $a) {    $a->go();}test(new A());

Trait

单继承语言PHP的代码复用机制。

Trait Bt{    public function atest()    {        echo 'Hello ';    }        public function btest()    {        echo 'world';    }        public function ab()    {        $this->atest();        $this->btest();    }}class Test{    use Bt;        // 使用Bt Trait,便拥有了Bt所有的方法}$test = new Test;$test->ab();

继承多个Trait

Trait A{    public $name = 'tom';    public function a()    {        echo 'Hello ';    }}Trait B{    public function b()    {        echo 'world ';    }}class Test{    use A,B;    public function c()    {        echo $this->name;    }}$test = new Test;$test->a();$test->b();$test->c();        // Hello world tom

Trait 支持嵌套

Trait A{}Trait B{}Trait C{    use A,B;}Class Test{    use C;}

interface

接口是类的模板。在接口中只定义需要实现的空方法,这些方法在接口中不做具体实现。

接口是不能被实例化的。

Interface Person{    public function eat();   public function sleep();}class man implements Person{    public function eat()    {        echo 'eating...';    }        public function sleep()    {        echo 'sleeping...';    }}class L{    public static function factory(Person $user)    // 用接口作类型约束    {        return $user;    }}$user = L::factory(new Man());$user->eat();$user->sleep();

接口可以继承接口。

接口可以继承多个接口。
接口可以使用常量,叫接口常量,和类的常量使用方法相同

Interface Ia{    const ONE = 1;    public function eat();}Interface Ib{    public function sleep();}Interface AB extends Ia,Ib{}// class Test implements Ia,Ib        类可以同时继承多个接口class Test implements AB{    public function eat()    {        echo 'eating...';    }        public function sleep()    {        echo 'sleeping...';    }}$test = new Test;$test->eat();$test->sleep();echo Ia::ONE;    // 使用接口常量

abstract

抽象类不能被实例化。

如果至少有一个方法被声明为抽象的,那么这个类必须被声明为抽象的。
抽象方法只能声明,不能有具体功能实现。
抽象类可以有被实现的的方法。

继承抽象类,子类必须实现父类中所有的抽象方法。

这些方法的访问控制必须和父类一样,或者更宽松,不能比父类更严格。
方法的调用方式也必须匹配。类型和参数数量必须一致,但子类可以定义父类中不存在的可选参数。

abstract AB{    public function run()    {        echo 'running...';    }        abstract public function eat();    abstract public function sleep();}class Test extends AB{    public function eat()    {        echo 'eating...';    }        public function sleep($time = '21:00 PM')    // 可以定义父类方法中不存在的可选参数    {        echo 'sleep @ ' . $time;    }}

单例模式

只能被实例化一次,节省内存空间

class Test{    private static $instance = null;   private function __constrct()   {}   private function __clone()   {}   public static function getInstance()   {           if (!(self::instance instanceof self)) {              self::instance = new self();                  }           return self::instance;   }}$test = Test::getInstance();    // 多次调用也只是实例化一次

工厂模式

Interface CacheI{    public function set($key, $value);   public function get($key);   public function delete($key);}class Memcache implements CacheI{    public function set($key, $value){}   public function get($key){}   public function delete($ke){}}class Redis implements CacheI{    public function set($key, $value){}   public function get($key){}   public function delete($ke){}}class Cache{    public static function factory()    {        return new Memcache();    // 这里可以是继承了CacheI接口的任何类,比如Redis    }}$cache = Cache::factory();$cache->set('name', 'tom');$cache->get('name');$cache->delete('name');

转载地址:http://imdia.baihongyu.com/

你可能感兴趣的文章
关于redo size(一)
查看>>
We Know What @You #Tag: Does the Dual Role Affect Hashtag Adoption-20160520
查看>>
(转)Eclipse新增安卓虚拟机
查看>>
SpringMvc访问Controller去掉do
查看>>
PHPnow升级PHP 5.4与Mysql 5.5
查看>>
正则表达式验证邮箱格式
查看>>
如何围绕企业战略,建设BI驾驶舱?
查看>>
java多线程stop,suspend使用代码实际例子
查看>>
中小型研发团队架构实践三:微服务架构(MSA)
查看>>
Windows动态库学习心得
查看>>
在VMware虚拟机上安装Ubuntu 10.04
查看>>
LDA主题模型简介
查看>>
可拖动的DIV续
查看>>
关于“类型初始值设定项引发异常”
查看>>
MySql 小表驱动大表
查看>>
Redis 数据结构的底层实现 (一) RealObject,embstr,sds,ziplist,quicklist
查看>>
SQL语句注入的问题
查看>>
jQueryEasyUI Messager基本使用
查看>>
【C语言学习趣事】_33_关于C语言和C++语言中的取余数(求模)的计算_有符号和无符号数的相互转换问题...
查看>>
Tensorboard教程:显示计算图中节点信息
查看>>