Blogger Information
Blog 45
fans 3
comment 0
visits 45665
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
面向对象编程基础
残破的蛋蛋
Original
620 people have browsed it

面向对象编程基础

一、什么是面向对象?

面向对象编程(Object Oriented Programming),简称OOP。

它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。

面向对象的特性:

  1. 封装性
  2. 继承性
  3. 抽象(多态性)

二、类的声明与实例化

在声明一个类时,使用class关键字,声明这个类的与这个类所在的文件最好同名。

  • 以下是声明了一个Student类:
  1. class Student {
  2. // 在这里面声明成员属性和方法
  3. }

类的属性和方法有三种:

  1. public: 公开的,外部可以访问的;
  2. protected: 受保护的,仅限本类和子类访问;
  3. private: 私有,仅限本类使用,外部和子类无法访问。

以下是声明了一个Student类,以及类中的属性和方法的案例。

  1. class Student
  2. {
  3. // 属性:变量
  4. // 公有属性,外部、本类和子类可以访问
  5. public $name;
  6. // 受保护成员,仅限本类以及子类访问
  7. protected $gender;
  8. // private: 私有成员,仅限本类中的使用
  9. private $age;
  10. private static $score;
  11. // 构造函数
  12. // __construct()属于魔术方法,由系统自动调用
  13. // 在类的实例化过程中会调用它
  14. public function __construct($name, $gender, $age)
  15. {
  16. $this->name = $name;
  17. $this->gender = $gender;
  18. $this->age = $age;
  19. }
  20. // 方法
  21. public function getStuInfo() {
  22. return "姓名:{$this->name},性别:{$this->gender},年龄:{$this->age}岁。";
  23. }
  24. }

实例化Student类:

  1. $stu = new Student('张三', '男', 16);
  2. echo $stu->getStuInfo();

以上结果将输出:姓名:张三,性别:男,年龄:16岁。

访问类中的公有属性:

  1. echo $stu->name; // 张三

三、静态方法和成员(static)

当一个类的成员或方法被声明成了静态(static),那么,就无法通过类实例去访问了,必须使用类直接调用。

  1. class Staff {
  2. public $name;
  3. // 静态成员
  4. public static $salary;
  5. // 构造函数
  6. public function __construct(string $name, int $salary)
  7. {
  8. $this->name = $name;
  9. // 静态成员与类实例无关,因此不能用$this访问,直接使用类去调用
  10. self::$salary = $salary;
  11. }
  12. public static function staffSalary() {
  13. return '员工的工资:'.self::$salary;
  14. }
  15. }

实例化Staff类:

  1. $staff = new Staff('张三', 8899);
  2. // 使用类名访问静态属性
  3. echo Staff::$salary; // 8899
  4. // 使用类名访问静态方法
  5. echo Staff::staffSalary(); // 员工的工资:8899

四、类的继承(extends)

类的继承使用extends关键字,也就是对类的功能进行扩展。

  1. require 'Student.php';
  2. class Sub extends Student {
  3. // 类的继承一般有两个用处:
  4. // 1. 对父类方法进行重写;
  5. // 2. 对父类功能进行扩展。
  6. // 扩展一个属性,score:分数
  7. private $score;
  8. // 子类构造器,重写了父类的方法
  9. public function __construct($name, $gender, $age, $score)
  10. {
  11. // 调用父类成员
  12. parent::__construct($name, $gender, $age);
  13. $this->score = $score;
  14. }
  15. // 重写父类的getStuInfo()方法
  16. public function getStuInfo()
  17. {
  18. return parent::getStuInfo()."分数:{$this->score}";
  19. }
  20. // 增加一个新方法,判断学生成绩是否及格。
  21. public function isPass()
  22. {
  23. if ($this->score > 60) {
  24. return "该学生成绩已及格,分数为:{$this->score}";
  25. }
  26. }
  27. }
  28. $sub = new Sub('张三', '男', 16, 90);
  29. echo $sub->getStuInfo(); // 姓名:张三,性别:男,年龄:16岁。分数:90
  30. echo "<br>";
  31. echo $sub->isPass(); // 该学生成绩已及格,分数为:90

以上案例分别输出结果:

姓名:张三,性别:男,年龄:16岁。分数:90

该学生成绩已及格,分数为:90

五、Trait(代码复用)

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,为了使开发者能复用某些方法。
可以把trait理解为一个公共方法集,它借用了class语法实现了一个轻量级的“类”,但它不是类,所以不能实例化。

  • trait 示例
  1. trait userInfo {
  2. public function getUserInfo () {
  3. return "This is userInfo " . $this->name;
  4. }
  5. }
  6. class User
  7. {
  8. // 使用关键字use引入需要使用的trait
  9. use userInfo;
  10. }
  • 优先级
  1. trait userInfo {
  2. public function getUserInfo () {
  3. return "This is userInfo " . $this->name;
  4. }
  5. }
  6. class UserBase
  7. {
  8. public $username;
  9. // 引用trait
  10. use userInfo;
  11. public function __construct($username)
  12. {
  13. $this->username = $username;
  14. }
  15. public function getUserInfo () {
  16. return "This is UserBase " . $this->name;
  17. }
  18. public function getUserName() {
  19. return "UserBase:".$this->username;
  20. }
  21. }

以上代码在trait中和UserBase类中都声明了一个getUserInfo()方法,当在getUserInfo()类中引入trait里面的方法之后我们创建类实例,然后调用getUserInfo()方法,发现调用的是UserBase类里面的getUserInfo()方法。

trait冲突解决办法

当我同时声明了两个trait中有两个相同的方法getUserInfo(),那么在类中访问的时候回报错,具体案例如下:

  1. trait user1 {
  2. public function getUserInfo () {
  3. return "This is user1 ";
  4. }
  5. }
  6. trait user2 {
  7. public function getUserInfo () {
  8. return "This is user2 ";
  9. }
  10. }
  11. class User {
  12. use user1;
  13. use user2;
  14. }

以上代码会报错: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

解决办法是:优先级与别名:

  1. trait user1 {
  2. public function getUserInfo () {
  3. return "This is user1 ";
  4. }
  5. }
  6. trait user2 {
  7. public function getUserInfo () {
  8. return "This is user2 ";
  9. }
  10. }
  11. class User {
  12. use user1, user2 {
  13. // 1.优先级
  14. user1::getUserInfo insteadof user2;
  15. // 2.别名
  16. user2::getUserInfo as user2GetUserInfo;
  17. }
  18. }
  19. echo (new User('张三'))->getUserInfo(); // This is user1
  20. echo (new User('张三'))->user2GetUserInfo(); // This is user2

当父类trait与当前子类中存在同名成员时,如何解决?

  1. class SubUser extends User
  2. {
  3. use user3;
  4. public function fun () {
  5. return __METHOD__;
  6. }
  7. }

此时的结果是:SubUser::fun,说明子类的优先级高于父类的。

如果在父类与子类之间加了一个trait里面的一个同名函数,此时的优先级是什么样呢?

  1. trait user3{
  2. public function fun () {
  3. return __METHOD__;
  4. }
  5. }
  6. class SubUser extends User
  7. {
  8. use user3;
  9. public function fun () {
  10. return __METHOD__;
  11. }
  12. }
  13. echo (new SubUser())->fun(); // SubUser::fun

如果此时子类SubUser中没有fun方法呢?

  1. trait user3{
  2. public function fun () {
  3. return __METHOD__;
  4. }
  5. }
  6. class SubUser extends User
  7. {
  8. use user3;
  9. }
  10. echo (new SubUser())->fun(); // user3::fun

此时的结果是:user3::fun

这时,我们可以得出这个优先级的结果:自己拥有的 > trait > 父类的。

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post