php中的重载

  面向对象三大特性:继承、封装、多态。

  五大基本原则:单一职责原则、开放封闭原则(扩展开放、更改封闭)、替换原则(子类可以替换父类)、

                 依赖原则(上层依赖下层,接口)、接口分离原则

      重载:其他语言中包含属性重载、方法重载,在C++中还有运算符重载。

              在其他编程语言中,重载一般针对方法而言,满足参数类型或参数个数不一样就叫重载;

              在PHP中的重载是指动态地创建类属性和方法,通过魔术方法实现。

魔术方法

         以“__”开头的类方法保留为魔术方法。

         __construct()、__destruct()构造方法和析构方法,

         __call()、__callStatic()动态函数创建,

         __get()、__set()、__isset()、__unset()动态属性获取、创建、是否存在、注销,

         __wakeup()、__sleep()序列化和反序列化函数前后调用

    以下代码仿照https://my.oschina.net/sallency/blog/629206

<?php
class Person
{
    private $name, $age, $sex, $info;

    public function __construct( $name, $age, $sex )
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
        $this->info = sprintf("prepared by construct magic functionname: %s age: %d sex: %s",
            $this->name, $this->age, $this->sex);
    }

    public function getInfo()
    {
        echo $this->info . PHP_EOL;
    }
    /**
     * serialize前调用 用于删选需要被序列化存储的成员变量
     * @return array [description]
     */
    public function __sleep()
    {
        echo __METHOD__ . PHP_EOL;
        //序列化时只会存储 name age sex, info 不会被序列化
        //若要序列化info,则return ['name', 'age', 'sex','info'];
        return ['name', 'age', 'sex'];
    }
    /**
     * unserialize前调用 用于预先准备对象资源
     */
    public function __wakeup()
    {
        echo __METHOD__ . PHP_EOL;
        //不设置则为construct里的info方法
        $this->info = sprintf("prepared by wakeup magic function name: %s age: %d sex: %s",
            $this->name, $this->age, $this->sex);
    }
}

$boy = new Person( 'sallency', 25, 'male' );
//构造函数组装的 $info
$boy->getInfo();
//序列化时并不会存储 $info 属性
$temp = serialize($boy);
echo $temp . PHP_EOL;

//反序列化时会调用 __wakeup() 函数
$boy = unserialize($temp);
//__wakeup() 组装的 $info
$boy->getInfo();

其执行结果为

可在 __wakeup()、__sleep()中对序列化的内容进行选择和修改,如果没有return或者使用方法,则报错。若把__sleep

()中的return去掉,则报如下错误:

__toString()一个类被当作字符串时的处理方法,代码为PHP手册代码

<?php
// Declare a simple class
class TestClass
{
    public $foo;

    public function __construct($foo) 
    {
        $this->foo = $foo;
    }

    public function __toString() {
        return $this->foo;
    }
}

$class = new TestClass('Hello');
echo $class;

//最终输出“Hello”

__invoke()当尝试以调用函数的方式调用一个对象时调用,

<?php
class CallableClass 
{
    function __invoke($x) {
        var_dump($x);
    }
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));     //检测参数是否为合法的可调用结构

//输出内容如下
int(5)
bool(true)

__set_state()调用var_export()导出类时,方法会被调用,代码为php手册代码

<?php

class A
{
    public $var1;
    public $var2;

    public static function __set_state($an_array) // As of PHP 5.1.0
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];
        $obj->var2 = $an_array['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
                                            //    'var1' => 5,
                                            //    'var2' => 'foo',
                                            // ));
var_dump($b);

//输出
object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}

              echo、print、print_r、var_dump、var_export的区别:

                        echo:语言结构,可以不使用括号,不适用括号时可打印很多变量;

                              print:仅至此1个参数,echo输出速度比print快;

                            print_r:第二个参数为true时,会返回信息,不打印;

                              var_dump():会有变量的类型和长度,比print_r()显示得更详细;

                              var_export():返回合法的php代码。

var_export和var_dump的区别:

<?php

function returnArr(){
	return ['a'=>123,'b'=>'345'];
}

var_dump(returnArr());
#输出array(2) { ["a"]=> int(123) ["b"]=> string(3) "345" } 
var_export(returnArr());
#输出array ( 'a' => 123, 'b' => '345', )

__clone():当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值  (不太看得懂代码,存疑),

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
      
        // 强制复制一份this->object, 否则仍然指向同一个对象
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

//输出
Original Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)
Cloned Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值