1 面向对象介绍

1.1 介绍

​ 面向对象是一个编思想. 编程思想有面向过程和面向对象.

​ 面向过程: 编程思路集中的是过程上

​ 面向对象: 编程思路集中在参与的对象

1.2 好处

  1. 多人合作方便

  2. 减少代码冗余, 灵活性高

  3. 代码的可用性发挥到极致

  4. 可扩展性强

    OOP: 面向对象编程
    OOA: 面向对象分析
    OOD: 面向对象设计 

1.2 类和对象

​ 1. 对象是具体存在的事物,对象是由属性(变量)和(方法)组成的

​ 2. 类是具体相同属性和行为的一组对象的集合

​ 在开发的时候,先写类, 通过类创建对象, 通过对象调用方法和属性

​ 一个类可以创建多个对象

 

2 在PHP中实现类和对象

2.1 创建类

class 类名{
    //属性
    //方法
    //常量
}
类是由属性,方法,常量组成的
_________________________________________________________________________    
<?php 
    calss Student {
    };
 ?>

 

命名规则

  1. 以字母, 下划线开头, 后面跟的是字母, 数字, 下划线

    1. 不能用PHP关键字做类名

      1. 类名不区分大小写 (变量名区分, 关键字,类名不区分带小写). 类名用帕斯卡命名法 (大驼峰, 首字母大写)

2.2 对象实例化

​ 通过new关键字来实例化对象

<?php 
    // 定义类
    class Student{
    }
    //实例化
    $stu1=new Student();
    // 小括号可以省略
    $stu2=new Student;

2.3 对象的比较

对象的传递是地址传递

​ 相等: 结构和保存的值一样就相等

​ 全等: 指向同一个对象才是全等

<?php  
    class Stu{
​
    }
    $stu1=new Stu;
    $stu2=new Stu;
    // 对象传递的是地址
    $stu3=$stu2;
​
    //true
    var_dump($stu1==$stu2);
    //false
    var_dump($stu1===$stu2);
    //true
    var_dump($stu2===$stu3);

 

3 属性 & 方法 & 修饰符

3.1 属性

​ 属性本质就是变量

​ 通过->调用对象的成员 对象名 -> 属性名 对象名 -> 方法名()

<?php  
    // 定义类
    class Stu {
        public $name;
        public $add='地址不详';
    }
    // 实例化对象
    $stu=new Stu;
    $stu->name='Tom';
    $stu->add='北京';
    // 获取属性的值
    echo '姓名:'.$stu->name,'<br>';
    echo '地址:'.$stu->add,'<br>';
    // 添加属性
    $stu->age=20;
    echo '年龄:'.$stu->age,'<br>';
    //删除属性
    unset($stu->add);
    print_r($stu);
?>
 
3.2 方法
​ 方法的本质就是函数

 
<?php  
    // 定义类
    class Stu{
        public function show() {
            echo '这是show方法<br>';
        }
        function test(){
            echo '这是test方法<br>';
        }
    }
    // 调用方法
    $stu=new Stu;
    $stu->show();
    $stu->test();
?>

 

  1. 方法前面的public是可以省略的, 如果省略, 默认是public

    1. 属性前面的public不能省略

3.3 修饰符

​ 用来控制成员的访问权限

修饰符描述
public (公有的) 在类的内部和外部都能访问
private (私有的) 只能在类的内部访问
protected (受保护的) 在整个继承链上访问

​ 一般来说,属性都用私有的,通过公有的方法对私有的属性进行赋值和取值

​ 作用: 保证数据的合法性

<?php  
    class Stu{
        private $name;
        private $sex;
        function setInfo($name,$sex){
            if($sex!='男'&&$sex!='女'){
                echo '性别必须为男或女';
            exit;
        }
        $this->name=$name;
        $this->sex=$sex;
        }
        function getInfo(){
            echo '姓名: '.$this->name,'<br>';
            echo '性别: '.$this->sex,'<br>';
        }
    }
    $stu=new Stu;
    $stu->setInfo('tom','男');
    $stu->getInfo();
    echo '<hr>';
    $stu1=new Stu;
    $stu->setInfo('Sunny','难啊难');
    $stu->getInfo();
?>

4 类和对象在内存中的分布

4.1 分布

  1. 对象的本质是一个复杂的变量

    1. 类的本质是一个自定义的复杂数据类型

      1. 展区: 运行速度快, 体积小, 保存基本类型

      2. 堆区: 运行速度稍慢, 体积大, 保存复杂类型

      3. 实例化的过程就是分配内存空间的过程

      4. 对象保存在堆区, 将堆区的地址保存到栈区

4.2 计算机的内存管理

​ 计算机内存管理方式: 先进先出, 先进后出

​ 先进先出的内存管理方式一般用在业务逻辑中, 比如秒杀, 购票等等

​ 先进后出是计算机的默认内存管理方式

 

5 构造方法 & 析构方法

5.1 介绍

​ 构造方法也叫构造函数, 当实例化对象的时候自动执行

<?php  
    // 前面是两个下划线
    function __construct(){
    }
___________________________________________________________________
    
    class Stu{
        function __construct(){
            echo '这是构造方法<br>';
        }
    }
    new Stu();
    new Stu();
?>

​ 在其它语言中, 与类名同名的函数时构造函数, 在PHP中不允许这种写法

5.2 构造函数作用

​ 初始化成员变量

​ 构造函数可以带参数, 但不能有return

<?php  
    class Stu{
        private $name;
        private $sex;
        function __construct($name,$sex){
            $this->name=$name;
            $this->sex=$sex;
        }
        function show(){
            echo "姓名: {$this->name}<br>";
            echo "性别: {$this->sex}<br>";
        }
    }
    $stu=new Stu('Wang','男');
    $stu->show();
?>

5.3 析构方法

​ 当对象销毁的时候自动调用

​ 析构函数不可以带参数

function __destruct(){
    }
______________________________________________________________
    
<?php  
    class Stu{
        private $name;
        function __construct($name){
            $this->name=$name;
            echo "{$name}出生了<br>";
        }
        function __destruct(){
            echo "{$this->name}销毁了<br>";
        }
    }
    $stu1=new Stu('Tom');
    $stu2=new Stu('Wang');
    echo '<hr>';
?>

6 继承

6.1介绍

  1. 继承使得代码具有层次结构

    1. 子类继承父类的属性和方法, 实现代码的可重用性

      1. 使用extends关键字实现继承

      2. 父类和子类是相对的

class 子类 extends 父类{
}
____________________________________________________________
    
<?php  
    class Person{
        function show(){
            echo '这是人类<br>';
        }
    }
    // 子类继承父类
    class Stu extends Person{
    }
    $stu=new Stu;
    $stu->show();
?>    

执行过程

  1. 在Stu类中查找show(), 如果找到就调用, 找不到就到父类中查找

    1. 在Person类中查询show()

6.2 子类中调用父类成员

 
<?php  
    class Person{
        function show(){
            echo '这是人类<br>';
        }
    }
    // 子类
    class Stu extends Person{
        function test(){
            // 方法一
            // $person=new Person();
            // $person->show();
            
            // 方法二
            $this->show();
        }
    }
    $stu=new Stu;
    $stu->test();
?>
  1. 通过实例化父类调用父类的成员

  2. 通过$this关键字调用父类的成员

6.3 protected

​ protected: 受保护的, 在整个继承链上使用

//
<?php  
    class A{
        protected $num=10;
    }
    class B extends A {
        function getNum(){
            echo $this->num;
        }
    }
    $obj=new B();
    $obj->getNum();
?>
______________________________________________________________________
    
//
<?php  
    class A {
        function getNum(){
            echo $this->num;
        }
    }
    class B extends A {
        protected $num=10;
    }
    $obj=new B();
    $obj->getNum();
?>
______________________________________________________________________________
    
//
<?php  
    class A {
        function getNum(){
            echo $this->num;
        }
    }
    class B extends A {
        protected $num=10;
    }
    //整个继承链上只有A
    $obj=new A();
    //报错: Notice:Undefined property: A::$num 
    $obj->getNum();
?>

 

6.4 继承中的构造函数

  1. 如果子类有构造函数就调用子类的, 如果子类没有就调用父类的构造函数

    1. 子类的构造函数调用后, 默认不再调用父类的构造函数

通过类名调用父类的构造函数

 
类名::__construct()
_______________________________________________________________________
    
    <?php  
    class Person{
        public function __construct(){
            echo '这是父类<br>';
        }
    }
    class Stu extends Person{
        public function __construct(){
            Person::__construct();
            parent::__construct();
            echo '这是子类<br>';          
        }
    }
    new Stu();
?>

parent关键字表示父类的名字, 可以降低程序的耦合性

给父类传递参数

<?php  
    class Person{
        protected $name;
        protected $sex;
        public function __construct($name,$sex){
            $this->name=$name;
            $this->sex=$sex;
        }
    }
    class Stu extends Person{
        private $score;
        public function __construct($name,$sex,$score){
            parent::__construct($name,$sex);
            $this->score=$score;
        }
    public function getInfo(){
        echo "姓名: {$this->name}<br>";
        echo "性别: {$this->sex}<br>";
        echo "成绩: {$this->score}<br>";
        }
    }
    $stu=new Stu('Wang','男',90);
    $stu->getInfo();
?>

 

6.5 $this详解

​ this表示当前对象的引用, 也就是this保存的当前对象的地址

<?php  
    class A{
        public function __construct(){
            var_dump($this);
        }
    }
    class B extends A {
    }
    new A();
    echo '<br>';
    new B();
?>

6.6 多重继承

​ php不允许多重继承, 因为多次继承容易产生二义性.

​ 如何实现C继承A和B, 使用继承链