批改状态:合格
老师批语:
面向对象编程(Object Oriented Programming),简称OOP。
它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。
面向对象的特性:
在声明一个类时,使用class关键字,声明这个类的与这个类所在的文件最好同名。
Student类:
class Student {// 在这里面声明成员属性和方法}
类的属性和方法有三种:
以下是声明了一个Student类,以及类中的属性和方法的案例。
class Student{// 属性:变量// 公有属性,外部、本类和子类可以访问public $name;// 受保护成员,仅限本类以及子类访问protected $gender;// private: 私有成员,仅限本类中的使用private $age;private static $score;// 构造函数// __construct()属于魔术方法,由系统自动调用// 在类的实例化过程中会调用它public function __construct($name, $gender, $age){$this->name = $name;$this->gender = $gender;$this->age = $age;}// 方法public function getStuInfo() {return "姓名:{$this->name},性别:{$this->gender},年龄:{$this->age}岁。";}}
实例化Student类:
$stu = new Student('张三', '男', 16);echo $stu->getStuInfo();
以上结果将输出:姓名:张三,性别:男,年龄:16岁。
访问类中的公有属性:
echo $stu->name; // 张三
当一个类的成员或方法被声明成了静态(static),那么,就无法通过类实例去访问了,必须使用类直接调用。
class Staff {public $name;// 静态成员public static $salary;// 构造函数public function __construct(string $name, int $salary){$this->name = $name;// 静态成员与类实例无关,因此不能用$this访问,直接使用类去调用self::$salary = $salary;}public static function staffSalary() {return '员工的工资:'.self::$salary;}}
实例化Staff类:
$staff = new Staff('张三', 8899);// 使用类名访问静态属性echo Staff::$salary; // 8899// 使用类名访问静态方法echo Staff::staffSalary(); // 员工的工资:8899
类的继承使用extends关键字,也就是对类的功能进行扩展。
require 'Student.php';class Sub extends Student {// 类的继承一般有两个用处:// 1. 对父类方法进行重写;// 2. 对父类功能进行扩展。// 扩展一个属性,score:分数private $score;// 子类构造器,重写了父类的方法public function __construct($name, $gender, $age, $score){// 调用父类成员parent::__construct($name, $gender, $age);$this->score = $score;}// 重写父类的getStuInfo()方法public function getStuInfo(){return parent::getStuInfo()."分数:{$this->score}";}// 增加一个新方法,判断学生成绩是否及格。public function isPass(){if ($this->score > 60) {return "该学生成绩已及格,分数为:{$this->score}";}}}$sub = new Sub('张三', '男', 16, 90);echo $sub->getStuInfo(); // 姓名:张三,性别:男,年龄:16岁。分数:90echo "<br>";echo $sub->isPass(); // 该学生成绩已及格,分数为:90
以上案例分别输出结果:
姓名:张三,性别:男,年龄:16岁。分数:90
该学生成绩已及格,分数为:90
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,为了使开发者能复用某些方法。
可以把trait理解为一个公共方法集,它借用了class语法实现了一个轻量级的“类”,但它不是类,所以不能实例化。
trait userInfo {public function getUserInfo () {return "This is userInfo " . $this->name;}}class User{// 使用关键字use引入需要使用的traituse userInfo;}
trait userInfo {public function getUserInfo () {return "This is userInfo " . $this->name;}}class UserBase{public $username;// 引用traituse userInfo;public function __construct($username){$this->username = $username;}public function getUserInfo () {return "This is UserBase " . $this->name;}public function getUserName() {return "UserBase:".$this->username;}}
以上代码在trait中和UserBase类中都声明了一个getUserInfo()方法,当在getUserInfo()类中引入trait里面的方法之后我们创建类实例,然后调用getUserInfo()方法,发现调用的是UserBase类里面的getUserInfo()方法。
trait冲突解决办法
当我同时声明了两个trait中有两个相同的方法getUserInfo(),那么在类中访问的时候回报错,具体案例如下:
trait user1 {public function getUserInfo () {return "This is user1 ";}}trait user2 {public function getUserInfo () {return "This is user2 ";}}class User {use user1;use user2;}
以上代码会报错:Trait method getUserInfo has not been applied,because there are collisions with other trait methods on User in
E:\phpstudy_pro\WWW\phpcn\PHP\20210202\demo5.php on line 59。
解决办法是:优先级与别名:
trait user1 {public function getUserInfo () {return "This is user1 ";}}trait user2 {public function getUserInfo () {return "This is user2 ";}}class User {use user1, user2 {// 1.优先级user1::getUserInfo insteadof user2;// 2.别名user2::getUserInfo as user2GetUserInfo;}}echo (new User('张三'))->getUserInfo(); // This is user1echo (new User('张三'))->user2GetUserInfo(); // This is user2
当父类trait与当前子类中存在同名成员时,如何解决?
class SubUser extends User{use user3;public function fun () {return __METHOD__;}}
此时的结果是:SubUser::fun,说明子类的优先级高于父类的。
如果在父类与子类之间加了一个trait里面的一个同名函数,此时的优先级是什么样呢?
trait user3{public function fun () {return __METHOD__;}}class SubUser extends User{use user3;public function fun () {return __METHOD__;}}echo (new SubUser())->fun(); // SubUser::fun
如果此时子类SubUser中没有fun方法呢?
trait user3{public function fun () {return __METHOD__;}}class SubUser extends User{use user3;}echo (new SubUser())->fun(); // user3::fun
此时的结果是:user3::fun。
这时,我们可以得出这个优先级的结果:自己拥有的 > trait > 父类的。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号