博客列表 >类与对象的进阶知识--2018-9-6

类与对象的进阶知识--2018-9-6

晓明的博客
晓明的博客原创
2018年09月07日 11:18:08507浏览

一.匿名类的使用

   

实例

<?php
/**
 * 匿名类:
 * 1. php 7.0+ 才支持
 * 2. 类似于匿名函数,就是没有名称的类
 * 3. 匿名类适合于一次性的创建与引用
 * 4. 匿名类总是与: new 配套使用
 */

class BadPerson
{
    private $name = '西门大官人';
    public function story($name)
    {
        return $this->name.'喜欢上了: <span style="color:red">'.$name.'</span>';
    }
}

//有三种方式来访问 story()
//1. 对象
$badPerson = new BadPerson();
echo $badPerson->story('金莲妹妹'), '<hr>';
//2.匿名对象
echo (new BadPerson())->story('绿茶妹妹'), '<hr>';
//3.匿名类
echo (new class {
    private $name = '西门大官人';
    public function story($name)
    {
        return $this->name.'喜欢上了: <span style="color:red">'.$name.'</span>';
    }
})->story('神仙姐姐'), '<hr>';

// 匿名类的三种应用场景
//1. 匿名类中可以使用构造方法
echo (new class ('欧阳克'){
    private $name;
    // 匿名类中的构造方法
    public function __construct($name)
    {
        $this->name = $name;
    }

    public function story($name)
    {
        return $this->name.'喜欢上了: <span style="color:red">'.$name.'</span>';
    }
})->story('灭绝师太'), '<hr>';

//2. 在匿名类中可以继承其它类中的成员
class KungFu
{
    protected $kill;  //招数
    public function __construct($art='')
    {
        $this->kill = $art;
    }
    public function show()
    {
        return $this->kill ? : '黯然销魂掌';
    }
}

echo (new class ('西门大官人','御女剑法') extends KungFu {
    private $name;
    // 匿名类中的构造方法
    public function __construct($name,$art='')
    {
        parent::__construct($art);
        $this->name = $name;
    }

    public function story($name)
    {
        return $this->name.'喜欢上了: <span style="color:red">'.$name.'</span>';
    }
    public function show()
    {
        return $this->name.'的绝招是: '.'<span style="color:red">'.parent::show().'</span>';
    }
})->show(), '<hr>';
//3.可以在类声明中嵌套一个匿名类
class Anmal   // 宿主类, 父类的角色
{
    public $name = '狗';
    protected $color = '黑色';
    private $type = '哈士奇';

    protected function info ()
    {
        return '市 场售价3000元';
    }
    public function demo1()
    {
        // 宿主类中的私有成员不能在匿名类中直接使用
        // 可以通过在匿名类创建一个构造方法将宿主类中的私有成员进行注入
        // 3. 将宿主类中的私有属性做为匿名类的构造方法的参数传入即可
        return (new class ($this->type) extends Anmal {
            //1. 在匿名类中创建一个属性用来接收宿主类中的私有属性
            private $type;

            //2. 创建一个构造方法
            public function __construct($type)
            {
                $this->type = $type;
            }

            public function demo2()
            {
                return '我是嵌套匿名类中的方法: '. __METHOD__;
            }

            public function show()
            {
                return
                    '动物的名称是: ' .$this->name. '<br>'.
                    '动物的颜色是: ' .$this->color. '<br>'.
                    '动物的品 种是: ' .$this->type. '<br>';
            }

        });
    }
}

// 访问匿名类中的 demo2()
echo (new Anmal())->demo1()->demo2();

echo '<hr>';

echo (new Anmal())->demo1()->show();

运行实例 »

点击 "运行实例" 按钮查看在线实例


二.使用spl_autoload_register函数实现类的自动加载

  

实例

<?php
/**
 * 类的自动加载
 */
//include './class/Demo1.php';
//include './class/Demo2.php';


spl_autoload_register(function ($className){
    require './class/'.$className.'.php';
    //存在命名空间的情况下

//    $className = str_replace("\\","/", $className);
//    require './class/'.$className.'.php';
});

echo Demo1::CLASS_NAME, '<hr>';
echo Demo2::CLASS_NAME, '<hr>';

运行实例 »

点击 "运行实例" 按钮查看在线实例


三.抽象类的定义和使用

     抽象类
 * 1. abstract : 抽象
 * 2. 是类又不是类,与trait相似,不能被实例化
 * 3. 抽象类必须被继承才可以使用


实例

<?php
/**
 * 抽象类
 * 1. abstract : 抽象
 * 2. 是类又不是类,与trait相似,不能被实例化
 * 3. 抽象类必须被继承才可以使用
 */

abstract class Fruits
{
    protected $name;

    abstract public function eat();

    public function __construct($name)
    {
        $this->name = $name;
        return '构造器,实例化自动调用';
    }

}

class Apple extends Fruits
{
    protected $name ;

    public function eat()
    {
        return $this->name . '可以直接生吃';
    }
    public function __construct($name)
    {
        parent::__construct($name);
    }


}

echo (new Apple('苹果'))->eat(), '<hr>';

运行实例 »

点击 "运行实例" 按钮查看在线实例


四.接口的定义和使用

      * 接口: interface
 * 1. 类是对象的模板,对象是类的实例
 * 2. 接口就是类的模板,所以可以将接口看成一个特殊的类
 * 3. 接口中的方法只声明不实现,与抽象类的抽象方法是一样的
 * 4. 接口中可以声明常量,而且必须初始化(字面量)

  

实例

<?php
/**

 */

interface Animal
{
    // 接口常量
    const status = 'viable'; // 能存活的

    // 接口方法
    public function feeding($foods);
}

interface Feature
{
    public function hobby($hobby);
}



class Cat implements Animal
{
    private $name = '猫';

    //必须将接口中的接口方法实现
    public function feeding($foods)
    {
        return  $this->name . '吃: '. $foods;

    }
}

class Dog implements Animal, Feature
{
    private $name = '狗';
    //必须将接口中的Animal接口方法feeding实现
    public function feeding($foods)
    {
        echo  $this->name . '吃: '. $foods;
        return $this;
    }

    public function hobby($hobby)
    {
        echo $hobby;

    }
}

// 实例化
//echo (new Cat())->feeding('老鼠');
//echo '<hr>';
(new Dog())->feeding('肉')->hobby('忠诚,勇敢');
//echo '<hr>';
//echo (new Dog())->hobby('忠诚,勇敢');

运行实例 »

点击 "运行实例" 按钮查看在线实例



五.对象的复制与克隆

     对象的复制与克隆
 * 1. 默认的情况下,对象复制是引用传递

  

实例

<?php
/**
 *
 */

class Member
{
    // 声明三个私有属性
    private $name; //全员名
    private $email; // 邮箱
    private $score; // 积分

    //构造方法
    public function __construct($name='',$email='',$score=0)
    {
        $this->name = $name;
        $this->email = $email;
        $this->score = $score;
    }

    //查询器
    public function __get($name)
    {
        return $this->$name;
    }
    //设置器
    public function __set($name,$value)
    {
        $this->$name = $value;
    }

    public function __clone()
    {
       $this->score = 0;
    }

}

// 创建会员对象
$member = new Member('peter','peter@php.cn',1000);
//访问测试
echo $member->score, '<hr>';
//复制对象
$member1 = clone $member; // 应该有一个方法,在复制之前自动执行
//$member1->score = 2000;
echo 'member1的积分: '. $member1->score, '<hr>';
echo 'member的积分: '. $member->score, '<hr>';
//var_dump($member === $member1);

运行实例 »

点击 "运行实例" 按钮查看在线实例

六.对象的序列化和反序列化以及调用函数

   

实例

<?php
/**
 * 对象的序列化
 */
//$num = 500;
//echo serialize($num),'<hr>'; // i:500;
//$name = 'peter';
//echo serialize($name), '<hr>'; // s:5:"peter";
//$course = ['html','css','javascript'];
//echo serialize($course), '<hr>';

class Db
{
    //连接参数与返回值
    public $db = null;
    public $host;
    public $user;
    public $pass;

    //构造方法
    public function __construct($host='127.0.0.1', $user='root', $pass='root')
    {
        $this->host = $host;
        $this->user =  $user;
        $this->pass = $pass;
        // 确保实例化对象的时候能自动连接上数据库
        $this->connect();
    }

    //数据库连接
    private function connect()
    {
        $this->db=mysqli_connect($this->host,$this->user,$this->pass);
    }

    //对象序列化的时候自动调用
    public function __sleep()
    {
        return ['host','user','pass'];
    }

    //反序列化:
    public function __wakeup()
    {
        $this->connect();
    }

}

$obj = new Db();
/**
 * 对象序列化的特点:
 * 1. 只保存对象中的属性,不保存方法
 * 2. 只保存类名,不保存对象名
 */

echo serialize($obj),'<hr>';
$tmp = serialize($obj);
var_dump(unserialize($tmp));

运行实例 »

点击 "运行实例" 按钮查看在线实例


五.是trait关键字,变相的实现多继承

      * Trait 是什么东西?
 * 1. php 只能实现单继承,trait打破了限制
 * 2. trait 是代码复用机制(函数, 类的继承)
 * 3. trait 使的类的语法,但不是类,所以不能实例化
 * 4. triat 相当于方法集

实例

<?php
/**

 */

if (!class_exists('Person')) {
    class Person
    {
        protected $name;
        public function __construct($name='小明')
        {
            $this->name = $name;
        }

        public function study($course='php')
        {
            return $this->name . '在学习: ' . $course;
        }
    }
}

// 创建一个trait特性类
trait Course
{
    public $frient = '小华';
    public function study($name='踢足球')
    {
        return $this->name .'在学习'. $name;
    }
}

trait Recreation
{
    public $friend = '小军';
    public function study($name='打篮球')
    {
        return $this->name.'和'.$this->friend.$name;
    }
}

//问题1: 父类Person与triat类Course之间的关系?
// trait 类位于 Person 与 Student之间
class Student extends Person
{
//    use Course;  // 导入了一个trait 类
//    use Recreation;

    use Course, Recreation {
        Course::study insteadof Recreation;
        Recreation::study as MySport;
    }



}

$student = new Student();

echo $student->study(), '<hr>';
echo $student->MySport(), '<hr>';

运行实例 »

点击 "运行实例" 按钮查看在线实例


  

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议