06-类与对象基础与命名空间初步

1、类与对象基本知识

<?php

namespace _0815;


/**
 * 1.属性重载: __get(),__set()
 * 2.方法重载:__call(name,$args),__callStatic(name,$args)
 */

//面向对象的三大特征:封装,重载,继承
class User
{
    // private:私有,封装
    // private int $age = 20;
    //一般不会一个一个声明私有变量,可以直接声明一个数组
    private array $data = [
        'age' => 20,
    ];

    //查询接口/属性拦截器/魔术方法/属性重载:可以拦截对私有属性的访问,然后转移到一个指定的方法去进行

    public function getAge()
    {
        return $this->age;
    }
    //如何把访问属性的非法请求重定向到一个方法呢

    public function __get($name)
    {
        if (array_key_exists($name, $this->data)) {
            //$this后面的变量不写$
            // return $this->data[$name];
            $result = $this->data[$name];
        } else {
            // return "$name 属性不存在";
            $result = "$name 属性不存在";
        }

        //对于有些编辑器,有多个return时,会有警告
        return $result;

        //三元
        // return array_key_exists($name,$this->data)?$this->data[$name] : "$name 属性不存在";
    }


    //非法请求指对没有的方法进行请求时所执行的操作


    //可以自动拦截对于方法的非法访问
    public function __call($name, $args)
    {
        //第一个参数是方法名称
        //第二个参数是以数组表示的参数列表
        printf('方法名:%s<br>参数列表:<pre>%s</pre>', $name, print_r($args, true));
    }

    //拦截静态方法的非法请求
    public static function __callStatic($name, $args)
    {
        //第一个参数是方法名称
        //第二个参数是以数组表示的参数列表
        printf('方法名:%s<br>参数列表:<pre>%s</pre>', $name, print_r($args, true));
    }
}

$user = new User();
//  echo $user->$age;会报错,不能访问私有属性
echo $user->getAge() . '<hr>';

echo $user->age . '<hr>';

echo $user->age1 . '<hr>';

//非静态方法,类实例来访问
$user->hello('朱老师', '506174602');

//静态方法,类访问
User::world(100,200);

//ThinkPHP,查询构造器,数据库操作
class Query
{
    //当这个查询类实例化时,应该自动连接数据库
    // public function __construct()
    // {
    //     self::$connect()
    // }
    public function table($table)
    {
        return $this;
    }
    public function where($table)
    {
        return $this;
    }
    public function find()
    {

    }
}

//查询入口类
class Db
{
    public static function __callStatic($name, $arguments)
    {
        // echo $arguments[0];
        return call_user_func_array([new Query(),$name],$arguments);
    }
}
Db::table('think_user');
// Db::table('think_user')->where('id',1)->find();

上述运行结果:

 2、类的继承与扩展

<?php

namespace _0815;

/**
 * 类的扩展/抽象/最终
 * 1.可继承的成员:protected
 * 2.extends:类成员的来源
 * 3.parent:父类引用
 */

class Person
{
    //属性
    //public:公共成员,当前类,类外部都可见
    public $email = 'a@qq.com';
    //private:私有成员,仅限当前类,类外部不可见
    private int $id = 10;
    //protected:受保护的,用在当前类,以及他的子类中,外部不可见
    protected string $name;

    //public>protected>private
    //类中,类外,子类,public
    //类中,子类:protected
    //类中:private

    //方法

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

    //自定义方法
    protected function getInfo(): string
    {
        return $this->name;
    }
}

//继承/扩展一个类
//一旦执行了extends,就相当于把父类除了private的代码全部复制到当前类中
class Stu extends Person
{
    //只需要扩展父类中的"属性和方法"

    //1.属性扩展

    //之前的
    //private string $name;
    //扩展的
    private string $lesson;
    private int $score;

    //2.方法扩展
    //构造方法
    public function __construct($name, $lesson, $score)
    {
        //parent:引用父类
        parent::__construct($name);
        $this->lesson = $lesson;
        $this->score = $score;
    }

    //函数重写
    public function getInfo(): string
    {
        return parent::getInfo() . '同学,(' . $this->lesson . '),成绩:' . $this->score . '<br>';
    }
}

$stu = new Stu('小王', 'php', 90);
echo $stu->getInfo();

//2.禁用父类,仅允许通过它的子类来访问父类成员
//把当前类,声明为"抽象类":abstruct

abstract class Demo1
{
    public string $name = 'admin';
    // public function getInfo($name)
    // {
    //     return 'Hello ,' . $name;
    // }

    //如果某个方法没有具体实现,应该声明成抽象方法
    abstract public static function getInfo($name);
}

class Demo2 extends Demo1
{
    //在子类中,必须将父类中的抽象方法实现
    public static function getInfo($name)
    {
        return 'Hello ,' . $name;
    }
}

echo Demo2::getInfo('朱老师');

//抽象类:强制要求必须继承才能使用

//最终类:禁止继承,直接用

final class Demo3
{

}
// class Demo4 extends Demo3
// {

// }

上述运行结果:

 3、接口

<?php
namespace _0815;

//接口:升级版的抽象类

//接口一般首字母用i
interface iUser
{
    //常量
    const NATION = 'CHINA';

    //方法:public
    public function m1();

    public function m2();
}

//工作类:实现了接口的类

class Demo1 implements iUser
{
    //接口的抽象方法,必须在工作类中全部实现
    //如果声明为抽象类,就不用全部实现了
    public function m1()
    {

    }

    public function m2()
    {

    }
}

//如果实现类仅实现了接口的一部分抽象方法,应该声明为抽象类
abstract class Demo2 implements iUser
{
    public function m1()
    {

    }

}

//Java,PHP是单继承,C++是多继承
//PHP可以通过接口来实现多继承

interface A
{

}
interface B
{
    
}
interface C
{
    
}

//Test类,同时从三个接口中获取成员,间接实现"多继承"

class Test implements A,B,C
{

}

interface iDB
{
    //insert
    public static function insert(array $data);

    //update
    public static function updata(array $data,string $where);

    //delete 
    public static function delete(string $where);

    //select
    public static function select(array $options);
}

abstract class aDb
{
        //insert
        public static function insert(array $data)
        {}

        //update
        public static function updata(array $data,string $where)
        {}
    
        //delete 
        public static function delete(string $where)
        {}
    
        //select
        public static function select(array $options)
        {}
}

class Db extends aDb
{

}

4、命名空间基础

<?php

namespace one;

//命名空间解决了:全局成员的命名冲突,借鉴了同名文件可以存入不同的目录下面

class Demo1
{
    public static string $name = 'admin';
}

//当存在命名空间时,全局成员应该使用完整的名称
//类名 = 空间名称\类名
//::class 获取类的完整名称

echo Demo1::class . '<hr>';

namespace two;

class Demo1
{

}

echo Demo1::class . '<hr>';

//跨空间访问
// echo one\Demo1::$name;

//实际访问的是:'two\one\Demo1'

//跨空间访问时,必须从根空间/全局空间开始查询: \

$arr = new Demo1;
echo \one\Demo1::$name;

5、命名空间的路径名称

<?php

namespace _0815;

//1.当前路径:非限定名称    Index
//2.相对路径:限定名称      two\Index
//3.绝对路径:完全限定名称   \one\two\Index

namespace one;

class Index
{
    public static function show()
    {
        return __METHOD__;
    }
}

echo Index::show() . '<hr>';

//如果我在one空间中,访问 one\two中的成员
echo \one\two\Index::show() . '<hr>';

//全局成员的前缀,默认就是当前的空间名
//因为本身就在one里面,所以\one可以不写

echo two\Index::show() . '<hr>';

//use默认使用完全限定名称的类名/绝对路径

echo \one\two\three\Index::show() . '<hr>';
use \one\two\three\Index as UserIndex;

//起了别名之后,下面就不必写这么长了

echo UserIndex::show() . '<hr>';

//如果当前空间中没有index类,可以进一步简化
//use one\two\three\Index as Index
//如果当前类别名称与原始类名相同,可以不写
//即use one\two\three\Index as Index 等价于 use one\two\three\Index

//如果当前空间中有Index类,就不能省去as

//insteadOf:trait中解决命名冲突

//trait:一个特殊的类




//空间可分层管理
namespace one\two;

class Index
{
    public static function show()
    {
        return __METHOD__;
    }
}

echo Index::show() . '<hr>';

//空间可分层管理
namespace one\two\three;

class Index
{
    public static function show()
    {
        return __METHOD__;
    }
}

echo Index::show() . '<hr>';


上述运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七色的天空

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值