抽象类、trait、继承不完全笔记
后期静态绑定原理与实现
class BaseClass
{
public static function outputClassName()
{
echo '当前类名:' . __CLASS__;
}
public static function outputCurrentClassName()
{
// 输出结果:当前类名:BaseClass
// self::outputClassName();
// 输出结果:当前类名:subClass
// static::称为静态绑定,不再被解析为定义当前方法所在的类
static::outputClassName();
}
}
class subClass extends BaseClass
{
public static function outputClassName()
{
echo '当前类名:' . __CLASS__;
}
}
subClass::outputCurrentClassName();
使用 self::
和 static::
显示的不同结果:
属性、方法重载(拦截器)
当用户访问一个无权限或不存在的属性、方法时,通过魔术方法动态的创建类的属性和方法。
属性重载
属性的重载通过 __set
,__get
,__isset
,__unset
来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。
class Car
{
private $array = [];
// 在给私有的属性赋值时,__set() 被调用
public function __set($key, $value)
{
$this->array[$key] = $value;
}
// 读取私有的属性值时,__get() 被调用
public function __get($key)
{
if (isset($this->array[$key])) {
return $this->array[$key];
}
return null;
}
// 当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用
public function __isset($key)
{
if (isset($this->array[$key])) {
return true;
}
return false;
}
// 当对不可访问属性调用 unset() 时,__unset() 会被调用。
public function __unset($key)
{
unset($this->array[$key]);
}
}
$car = new Car;
// 使用 __get() 动态创建并赋值 brand
$car->brand = '宝马';
echo "这是一辆 {$car->brand} 牌汽车";
// 可以 isset 变量
printf("isset 检测 \$brand 变量的值:%s", print_r(isset($car->brand), true));
// 可以释放私有变量
unset(isset($car->brand));
方法拦截器
- 在对象中调用一个不可访问方法时,__call() 会被调用。
- 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。
- $name 参数是要调用的方法名称。$args 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
class Demo
{
// 方法拦截器
public function __call($name, $args)
{
echo 'demo 方法并不存在,所以直接输出这里的内容。<br>';
}
// 静态方法拦截器
public static function __callStatic($name, $args)
{
echo '静态 demo 方法并不存在,被我拦截了。';
}
}
$demo = new Demo;
$demo->demo();
Demo::demo();