摘要:一.类的继承 + 类的继承,是为了代码复用 + PHP只支持单继承 + 继承必须发生在二个或二个以上的类之间 + 父类也叫超类,基类,子类也叫派生类 之前我们是用函数来实
一.类的继承
+ 类的继承,是为了代码复用
+ PHP只支持单继承
+ 继承必须发生在二个或二个以上的类之间
+ 父类也叫超类,基类,子类也叫派生类
之前我们是用函数来实现代码复用,现在我们用类的继承来实现代码复用
类继承使用 extends关键字
* 继承环境下:
* protected,public 可以在子类中访问
* 访问限制符是受到类作用域限制的
* 类常量,不受限制的.可以在子类中直接使用
class ParentClass
{
public $name;
protected $course;
private $salary;
const SITE_NAME = 'PHP中文网';
//构造方法
public function __construct($name,$course,$salary)
{
$this->name = $name;
$this->course = $course;
$this->salary = $salary;
}
//访问本类私有成员
public function getSalary()
{
return $this->salary;
}
public function getCourse()
{
//受保护的成员,可以在子类中访问
return $this->course;
}
}
//创建子类,继承自parentClass 类
class ChildClass extends ParentClass
{
//子类中允许重写父类中的同名方法,也叫多态
public function getCourse()
{
//受保护的成员,可以在子类中访问
// return $this->course;
return $this->name.'的成名地点是'.parent::getCourse();
}
public function getSalary()
{
// return $this->salary;
}
}
$child = new ChildClass('张辽','白门楼',8000);
echo $child->name.'<br>';
//echo $child->course.'<br>';//访问失败 父类受保护的属性
echo $child->getCourse().'<br>';
//echo $child->getSalary(); //失败 不可以访问父类中私有属性
echo ChildClass::SITE_NAME.'<br>';二.范围解析符的使用
* 使用场景:
+ 访问类中的静态成员
+ 访问类中的常量
* 使用主体:
+ 在类中使用关键字:self static parent
+ 在类外可直接使用类名:className
class Book
{
//声明一个普通的动态成员属性
public $name = "mysql从删库到跑路";
//声明静态成员的属性
protected static $author = '朱老师';
//类常量,不要设置访问限制,本身就属于类的
const PRICE = 99;
//动态方法,既可以访问动态成员,也可以访问静态成员
public function getInfo1()
{
//普通动态成员
// return $this->name;
//静态成员
//尽管可以在普通方法中访问静态成员,但是推荐尽可能不用这样做
// return self::$author; //self::$成员名
return self::PRICE;
}
//静态方法,属于类的必须要用类来调用,可以被所有该类的对象所共享
public static function getInfo2()
{
//普通动态成员,不能访问
// return $this->name;
//静态成员
// return self::$author; //self::$成员名
return self::PRICE;
}
}
//子类Study 继承自Book类
class Study extends Book
{
public static function getInfo3()
{
//访问父类的静态成员
// return Book::$author;
//应该使用当前父类的引用标识:parent
// return parent::$author;
return static::$author;
}
}
$book = new Book();
//echo $book->name;
echo $book->getInfo1();
//echo Book::getInfo2();
$study = new Study();
echo $study->getInfo3();三.static关键字
用处如下:
+ 定义与访问类中的静态成员;
+ 访问类常量
+ 后期静态绑定(延迟静态绑定)
class MyClass
{
//const 定义类常量
const DOMAIN = 'www.php.cn';
//static 定义静态属性:被类的所有实例所共享
public static $desc = '免费公益,海量资源';
//静态方法
public static function getDesc()
{
//类常量
// $domain = self::DOMAIN;
$domain = static::DOMAIN;
//静态属性
// $desc = self::$desc;
$desc = static::$desc;
return '('.$domain.')'.$desc;
}
}
//外部访问类中的静态属性
echo MyClass::$desc.'<br>';
echo MyClass::getDesc();四.后期静态绑定 (static)
+ 使用在静态继承的上下文环境中;
+ 动态匹配静态成员的调用者,而不是声明者;(谁调用我,我就是谁)
+ 静态方法与调用者的绑定在运行阶段才可以确定
//定义一个父类
class Father
{
//静态属性
public static $money = 50000;
//静态方法
public static function getClass()
{
//返回当前类名
return __CLASS__;
}
//静态方法
public static function getMoney()
{
// return self::getClass().'=>'.self::$money; //如果这样定义子类继承之后调用返回的是父类的self
//static用在静态继承的上下文中,调用者是动态的,动态设置静态成员的调用者(调用主体)
return static::getClass().'=>'.static::$money;
}
}
//定义子类,继承自Father
class Son extends Father
{
//覆写父类的静态属性
public static $money = 30000;
//覆写父类的静态方法
public static function getClass()
{
//返回当前类名
return __CLASS__;
}
}
//调用Father中的静态方法,来获取一下类名
echo Father::getClass().'<br>';
echo Father::getMoney().'<br>';
//调用子类Son类中的静态成员
echo Son::$money.'<br>';
echo Son::getClass().'<br>';
echo '<hr>';
//子类中调用父类中的getMoney()
echo Son::getMoney(),'<br>'; //希望返回Son::30000 而现在返回的是父类的值 改成static就变成希望的返回值了五.重载技术
+ 重载: 动态创建类属性和方法;
+ 属性重载:
* __set($name,$value)
* __get($name)
* __isset($name)
* __unset($name)
+ 方法重载: (当用户调用一个不存在的普通方法时触发__call 当用户调用一个没有访问权限或着不存在的静态方法自动调用__callstatic)
* __call($method,array $args)
* __callStatic($method,array $args)
重载的实现手段:通过魔术方法
1.属性重载
__set(), __get() __isset() , __unset() 当设置,调用,判断是否存在,销毁 类中不存在的属性,或者不可访问的属性时 ,会调用属性重载
class Visit
{
protected $data = []; //声明一个空数组
public function __isset($name) //$name属性不存在或者受保护的时候调用
{
return isset($this->data[$name]); //因为这个$name属性不存在 返回false
}
public function __get($name) //当调用的$name 属性不存在或者受保护的时候, 设置$data的一个值
{
return $this->data[$name];
}
public function __set($name,$value) //当设置$name 的值 不存在或者受保护的时候, 设置$data的一个元素为这个不存在的值
{
$this->data[$name] = $value;
}
public function __unset($name) //当销毁一个不存在的值或者受保护的属性 提示不让他销毁
{
echo '禁止销毁';
}
}
$visit = new Visit();
if(isset($visit->table)){ //判断是否存在
echo $visit->table,'<br>'; //存在就输出它
}else{
$visit->table = 'table_staff'; //更新操作 不存在就设置他
}
//因为上边他不存在,所以走的else __set我设置方法让他给$data['table']设置了值'table_staff' 当我调用不存在的table属性, __get 我设置的让他返回$data['table']的值 ,所以返回成功了
echo $visit->table,'<br>'; //table_staff
unset($visit->table); //禁止销毁2,方法重载 __call(),__callStatic()
当访问一个不存在的一个动态普通方法的时候会自动调用__call()
当访问一个不存在的一个静态方法的时候会自动调用__callStatic()
方法重载更多用在跨类的方法调用上
require 'public/Site.php';
class Web
{
//当访问一个不存在的一个动态普通方法的时候会自动调用
public function __call($name, $arguments)
{
// return '方法是:'.$name.'<br>'.'参数列表:'.var_export($arguments,true);
//方法重载更多用在跨类的调用上
return call_user_func_array([(new Site),'show'],$arguments); //返回回到函数处理的结果 将$arguments(array)当做参数传到实例化对象Site的show方法中
}
//当访问一个不存在的一个静态方法的时候会自动调用
public static function __callStatic($name, $arguments)
{
// return '方法是:'.$name.'<br>'.'参数列表:'.var_export($arguments,true);
//方法重载更多用在跨类的调用上
return call_user_func_array(['Site','add'],$arguments); //将argunments当做参数传入到Site类中的静态方法add中
}
}
$web = new Web();
//访问一个不存在的方法
echo $web->show('php中文网','海量资源,公益免费').'<hr>';
//访问一个不存在的静态方法
echo Web::add(30,50);
批改老师:韦小宝批改时间:2018-11-26 11:12:55
老师总结:嗯!不错!写的很棒!不要骄傲!继续加油吧