Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:
优点:
1.存在多个实例,但是静态成员在内存中,只占一份
2.静态成员,执行效率比实例化高缺点:
静态成员不能自动销毁,实例化就会自动销毁
抽象类:设计类与实现类是分离的,可以为子类提供一些,公用的方法,作为子类重写的模板来使用
创建抽象类
// 创建抽象类
abstract class A
{
// 抽象方法
abstract public function ff1();
abstract public function ff2();
}
// new A(); // 抽象类不能实例化,不能生产出来对象,但是可以通过继承抽象类进行实例化
// 抽象类继承抽象类,
abstract class B extends A
{
// 构造方法在抽象类里使用
protected $name1;
protected $name2;
public function __construct($name1, $name2)
{
$this->name1 = $name1;
$this->name2 = $name2;
}
// 继承了抽象类,抽象类里的所有抽象方法也要重写,
// 如果抽象类方法不全部都重写,那么只能自己也转变为抽象类
// 抽象类里面也可以使用普通方法
public function ff1()
{
return '我是: ' . $this->name1 . ',继承的抽象类A重写ff1';
}
}
// 继承抽象类B 重写B没有重写的方法
class C extends B
{
public function ff2()
{
return '我是: ' . $this->name2 . ',继承的抽象类B重写抽象类A中的ff2';
}
}
$a = new C('ff1', 'ff2');
echo $a->ff1();
echo '<hr>';
echo $a->ff2();
类常量关键词:const
常量
class Cl
{
// const 常量关键词
const CL_NAME = '常量';
// 不能用普通方法访问,要用静态访问方法 类名::
public function get_name()
{
return self::CL_NAME;
}
}
echo Cl::CL_NAME;
$obj = new Cl();
echo $obj->get_name();
使用接口的时候,如果接口里有静态成员,重写的时候也要按照静态的方法写
接口的运用
// 创建抽象类
abstract class A
{
// const 常量
const APP_NAME = 'Mac';
// 抽象方法
abstract public function az($cj);
}
// 关键词 interface 创建接口
interface Cja
{
public static function az_Cja($a);
}
interface Cjb
{
public function pj($b, $c);
// 方法和函数一样,可以接收多个
public function az_CJb($a);
}
// 用关键词 implements 来使用接口
// 使用多个接口,用英文逗号隔开
class B extends A implements Cja, Cjb
{
public function az($a)
{
return '安装成功: ' . $a;
}
// 使用接口,接口里有静态成员,那么重写的时候就要用静态的方法
public static function az_Cja($a)
{
return '安装成功: ' . $a;
}
public function pj($b, $c)
{
return $b . '<hr>' . $c;
}
public function az_CJb($a)
{
return '安装成功: ' . $a;
}
}
$obj = new B();
echo $obj->pj('苹果台式电脑', '苹果笔记本');
echo '<hr>';
echo $obj->az('A安装包');
echo '<hr>';
echo B::az_Cja('B插件包'); // 静态成员用 类名:: 访问
echo '<hr>';
echo $obj->az_CJb('C插件包');
静态继承的时候,是上下文环境,在调用过程中,没有正确识别调用者
后期静态绑定的使用
class A
{
public static function ff()
{
return '这是A类的ff';
}
public function show()
{
// return $this->ff(); // 静态成员不允许用 $this
// return self::ff(); // 访问结果不匹配,要结果对应,实例化谁,就找谁拿结果
return static::ff(); // 后期静态绑定,用 static关键词 替换 self关键词, 可以让实例化与结果匹配
}
}
class B extends A
{
public static function ff()
{
return '这是B类的ff';
}
}
$a = new A(); // 实例化 A
echo $a->ff(); // 返回: 这是A类的ff
echo '<hr>';
$b = new B(); // 实例化 B
echo $b->ff(); // 返回: 这是B类的ff
__destruct 析构方法,在类注销(注销结束)的时候自动执行
析构方法
class A
{
public $name;
public function __construct($name)
{
$this->name = $name;
}
// 析构方法是最后结束了执行
public function __destruct()
{
echo '执行完了';
}
}
$a = new A('析构方法');
$name = $a->name;
echo $a->name;
echo '<hr>';
unset($a); // 删除类,,相当于把类执行完了,结束这个类
echo '<hr>';
echo $name;
__set 修改成员的时候触发
修改设置需要两个参数
$key 相当于要修改的参数
$value 相当于要修改的值
通过返回 $this的key(参数名) = 要修改的值,进行修改
class A
{
protected $age;
protected $jimi;
private $name;
public function __construct($name, $age, $jimi)
{
$this->name = $name;
$this->age = $age;
$this->jimi = $jimi;
}
// __get 有一个参数
public function __get($n)
{
// 判断
if ($n == 'name' || $n == 'age') {
// return $name; // 这里的name和 类里的 $name 不是同一个
// __get的参数: 我们要找的成员名字,我们在我们找name它就是name ,它就相当于是数组的下标一样
// return $n;
// $n 代表要找的成员名字
return $this->$n;
}
// 判断它是否存在
// empty 只要是没有值,也会当 true
if (empty($this->$n)) {
return '不存在';
}
return '抱歉,你暂时没有权限';
}
// 设置需要两个参数
public function __set($key, $value)
{
// $key 相当于要修改的参数
// $value 相当于要修改的值
// 通过返回 $this的key(参数名) = 要修改的值,进行修改
return $this->$key = $value;
}
}
$a = new A('科学家', '25', '核心技术');
echo $a->name . ',' . $a->age; // 科学家25
echo '<hr>';
echo $a->jimi; // 抱歉,你暂时没有权限
echo '<hr>';
$a->age = 30; // 修改参数
echo $a->age; // 输出 30
__call 访问未定义的方法时触发
__call 有两个参数
第一个参数: 是访问的方法
第二个参数: 是方法的传值
示例
class A
{
public function __call($key, $value)
{
return '方法名: ' . $key . '<br>方法参数: <pre>' . print_r($value, true) . '不存在';
}
}
$a = new A();
echo $a->adds(10, 30, 50);
没有静态方法访问,就会执行 __callStatic魔术方法
示例
class A
{
// 静态触发的话,就要使用静态方法
public static function __callStatic($key, $value)
{
return '方法名: ' . $key . '<br>方法参数: <pre>' . print_r($value, true) . '不存在';
}
}
// 没有这个静态方法,就会执行 __callStatic 魔术方法
echo A::add(10, 30, 50);
关键词 | 解释 | |
---|---|---|
const | 定义类常量 | |
extends | 扩展类,用一个类去扩展它的父类(继承类) | |
public | 公开属性或者方法 | |
protected | 受保护的属性或者方法 | |
private | 私有属性或者方法 | |
static | 静态成员 | |
abstract | 抽象类或者方法 | |
interface | 创建接口 | |
implements | 实现接口 | |
final | 类不能被继承 | |
parent:: | 访问父类 | |
$this | 访问本类 | |
self:: | 访问本静态类 | |
namespace | 创建命名空间 |
方法 | 描述 | |
---|---|---|
__construct | 构造方法,实例类的时候自动调用 | |
__destruct | 析构方法,类执行完后,自动调用 | |
__call | 在对象中调用一个不可访问方法时调用 | |
__callStatic | 用静态方式中调用一个不可访问方法时调用 | |
__get | 获取不可见和未定义的属性,自动调用 | |
__set | 修改成员的时候,自动调用 | |
__isset | 当对不可访问属性调用 isset()或 empty()时调用 | |
__unset | 当对不可访问属性调用unset()时被调用 | |
__sleep | 执行serialize()时,先调用这个函数 | |
__wakeup | 执行 unserialize()时,先会调用这个函数 | |
__toString | 类被当成字符串的回应方法 | |
__invoke | 调用函数的方式调用一个对象时的回应方法 | |
__set_state | 调用 var_export()导出类时,此静态方法会被调用 | |
__clone | 当对象复制完成时调用 | |
__autoload | 尝试加载未定义的类 | |
__debugInfo | 打印所需调试信息 |