PHP7-2: 面向对象开发
PHP 面向对象
静态属性 static
// 使用场景: 类的一些公用属性和方法,值有可能改变
// 如何访问 静态属性呢
// 通过 self::方法 或者 属性 , 就可以访问到类的静态属性
# 切记: 静态属性和方法只能类自己访问,不能实例对象访问。
<?php
class People {
protected static $className = '大三老学长';
public function getClassName(){
echo '他是'.self::$className;
#他是大三老学长
}
}
const 类常量定义使用
// 使用场景: 值不会变化时,使用
// 如何访问const 常量
// self::常量名字
<?php
class Peole {
const NAME = '海军';
public function getName(){
echo self::NAME;
}
}
$hj = new Peole();
$hj->getName();
# 海军
禁止重写父类方法或者属性 final
//使用场景: 父类不想让子类重写自己的方法或者属性 时使用
# 使用 final
<?php
# 父类
class Peole {
const NAME = '海军';
# 在 function 前加 final
public final function getName(){
echo self::NAME;
}
}
# 子类
class Woman extends Peole {
public function getName(){
echo '子类不能重写父类';
}
}
$woman = new Woman();
$woman->getName(); # 调用时,结果报错
抽象类抽象方法
// 使用场景:子类继承了父类, 并且必须实现父类的某些方法 时使用
# 格式: abstract
# 注意: 类为抽象类时;不能实例化对象调用方法和属性,类本身也不能自身调用属性和方法。
<?php
abstract class Peole {
protected static $className = '大三老学长';
//抽象方法
abstract public function learn();
public function getClassName(){
echo '他是'.self::$className;
}
}
class Woman extends Peole {
public function getName(){
echo '子类不能重写父类';
}
public function learn(){
echo '有阅读的能力';
}
}
// 类为抽象类时不能实例化对象,也不能自己调用自己
// $hj = new Peole();
// $hj->getName();
// echo "<hr/>";
// $hj->getClassName();
class Woman extends Peole {
public function getName(){
echo '子类不能重写父类';
}
public function learn(){
echo '有阅读的能力';
}
}
$woman = new Woman();
$woman->getName();
$woman->learn();
变相多继承 Trait 使用
//使用场景: 当类需要继承多个基类时采用,(PHP以前一直是单继承)
// 格式:
#trait 变量名{} 类中使用trait: use 变量名
# 1.基本使用
<?php
trait Student {
public $name = '姓名';
public function getNames(){
echo __METHOD__;
}
}
class School {
use Student;
}
$smallSchool = new School();
echo $smallSchool->name;
$smallSchool->getNames();
Trait 优先级
# 2.优先级问题,
#2.1父类和基类有同样的方法,调用访问时会访问父类的方法
#2.2子类继承了父类,也使用了trait,调取同样的方法时,优先采 用trait的方法
<?php
trait Student {
public $name = '姓名';
public function getNames(){
echo '我是 trait';
}
}
class School {
use Student;
public function getNames(){
echo '我是 School';
}
}
class Teacher extends School {
use Student;
}
$teacher = new Teacher();
$teacher->getNames();
// 结果为: 我是 trait
// 当子类继承了父类, 父类和trait 有同样的方法, 子类实例对象调用同样方法名时,优先采用trait的方法
解决Trait 方法冲突 insteadOf as
// 应用场景: 当多个trait时,可能会有同名的方法,类的实例对象调用时,就会冲突;
# 解决办法: 1.insteadOf 2. as
# use 变量1,变量2{
# 变量1:: getNames insteadOf 变量2;
// 解释: 变量1的getNames 方法替代了 变量2
# Patriarch:: getNames as getToName;
// 解释: 将变量2的方法通过 as 别名,调用
# }
<?php
trait Student {
public $name = '姓名';
public function getNames(){
echo '我是 Student';
}
}
trait Patriarch {
public function getNames(){
echo '我是 Patriarch';
}
}
class School {
use Student,Patriarch{
Student:: getNames insteadOf Patriarch;
Patriarch:: getNames as getToName;
}
public function getNames(){
echo '我是 School';
}
}
$school = new School();
$school->getNames(); //我是 School
echo "<hr/>";
$school->getToName();
echo "<hr/>"; //我是 Patriarch
Trait 访问控制 protected
trait Patriarch {
protected function getNames(){
echo '我是 Patriarch';
}
}
class School {
use Patriarch{
Patriarch:: getNames as getToName;
}
}
$school = new School();
$school->getToName(); //访问就会报错,受保护的
Trait 使用情况
- Trait 中可以使用 abstract 方法
- Trati 中可以使用 静态方法
魔术方法
所谓魔术方法,它就是PHP 中提供了一些函数,在某些时刻自动调用,处理一些逻辑,执行时间不同。
类似于 生命周期, 钩子函数。
construct 构造函数
<?php
class Girl{
private $name;
public function __construct(String $names)
{
echo $this->name = $names;
}
}
new Girl('小红');
_set and _get
// 使用场景: 一般类的属性或者方法为私有或者受保护的,这样类的实例是不能直接访问和修改的,想访问类的这些属性就得使用 _set _get 方法, 当访问私有属性或者方法时,会自动调用_set and _get 方法中的内容。
# 格式: set 有两个参数 get有一个参数
public function __get($names)
{
echo '获取私有和受保护的属性时,自动调用';
return $this->$names;
}
public function __set($name, $value)
{
echo '设置私有和受保护的属性时,自动调用------';
$this->$name = $value;
}
# 注意: 如果类中没有创建这两个函数 _set _get ,在访问私有属性 方法和受保护属性方法就会警告。
#完整代码
<?php
class Car {
private $price = '$9w';
private $name = '奥迪';
public $place = '美国';
public function __get($names)
{
echo '获取私有和受保护的属性时,自动调用';
return $this->$names;
}
public function __set($name, $value)
{
echo '设置私有和受保护的属性时,自动调用------';
$this->$name = $value;
}
}
$car = new Car();
echo '<hr/>';
echo $car->name;
echo '<hr/>';
echo $car->place;
echo '<hr/>';
$car->prive = '22$';
echo $car->price;
# 输出内容
获取私有和受保护的属性时,自动调用奥迪
美国
设置私有和受保护的属性时,自动调用------获取私有和受保护的属性时,自动调用22$
_call
//使用场景: 当调用了类中不存在的方法时,程序会停止运行,为了防止 误调用,程序断开,使用_call 来处理此情况
# 格式
__call($functionName, $arg) 参数1为方法名 参数2 为传递参数
# 完整代码
<?php
class Car {
public function __call($functionName, $arg)
{
echo '类中没有该函数,函数名为:'.$functionName;
echo '<hr/>';
print_r($arg);
}
}
$car = new Car();
$car->run(1,2,3,4); //类中没有该函数,函数名为:run Array ([0] => 1[1] => 2[2] => 3[3] => 4 )
__callStatic
//使用场景: __callStatic 当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法。
# 格式
__callStatic($functionName, $arg) 参数1为方法名 参数2 为传递参数
#完整代码
<?php
class Car {
public function __call($functionName, $arg)
{
echo '调用函数名为'.$functionName;
echo '<hr/>';
print_r($arg);
}
public static function __callStatic($name, $arguments)
{
switch ($name) {
case 'fly':
echo 'Fly : -------> 通过switch 来判断执行不同的业务逻辑';
break;
default:
echo '您访问的静态方法类没有';
}
}
}
Car::fly();//Fly : -------> 通过switch 来判断执行不同的业务逻辑
echo '<hr/>';
Car::eat();//您访问的静态方法类没有
更多学习内容请访问: