zoukankan      html  css  js  c++  java
  • php面向对象之self关键字 、类的加载

    思考:类的内部的静态方法内可能会访问其他静态成员或者类常量,这个时候必须每次使用类名::那么如果类名修改的画岂不是很麻烦?  

    引入:静态成员或者类常量的访问时必须使用类名进行访问的,不过为了方便类名的更新,减少开发者维护成本,系统引入一个类似$this代表对象的方案,self关键字来代表当前类

    self关键字(自己  本身的意思)

      定义:self关键字是一种在类的内部(方法里面)使用,代替类名的写法,能够保障用户方便修改类名字。

      1.self是用来代替类名的,与范围解析操作符::一起使用

      

    <?php
    
    class fly{
        private static $count=0;
    
        static function show(){
            echo fly::$count;    //使用类名::静态成员访问
            echo self::$count;   //使用关键字self::静态成员访问
        }
    }
    
    
    fly::show();   //访问静态方法  返回 00  self关键字只能在类中使用
    ?>

      2.self也可以在类的内部方便实例化对象,比如构造方法被私有化之后,就没有办法在类外部实例化对象,此时可以在类内部进行对象实例化

    <?php
    
    class fly{
    
        private function __construct(){     //构造函数被私有化  此类不能被实例化
            
        }
    
    }
    
    
    
    new fly();   //报错
    
    ?>
    <?php
    
    class fly{
    
        private function __construct(){     //构造函数被私有化  此类不能被实例化
            
        }
    
        static function instance(){
            return new self();
        }
    }
    
    
    
    // new fly();   //报错
    
    $a=fly::instance();  
    
    var_dump($a);  //返回的是fly的对象  
    // 自己  只有类常量或者静态成员才能使用::范围解析操作符
    
    ?>

    总结 

      1.self是一种在类内部用来代替类名的关键字

      2.self可以用来在类内部访问静态成员(类常量也可以)

      3.self也可以在类内部用来实例化对象

     

    类的加载【重要】

      思考:类不管是直接访问静态成员还是先实例化然后访问类成员,都有一个前提:类必须在内存中存在,那是不是以为这所有类操作前,都必须先确认类在内存中是否存在呢?

      引入:类的任何操作都需要确认类在内存存在的,不过累文件通常是一个类单独形成一个文件的,所以在操作之前需要进行类的加载

      定义:所谓类的加载,本质是因为类的访问必须保证类在内存中已经存在,所以需要在用类之前将类所在的php文件加载到内存

      1.手动加载:即访问某个文件之前,使用包含将类所在的文件加载进来

    <?php
    //类文件
    class info{
    
    }
    
    ?>
    <?php
    
    include_once 'class_load.php';  //引用文件class_load.php 
    
    $a=new info();
    var_dump($a);
    ?>

    2.加载类文件是一种比较消耗资源的方式,所以有的时候不确认类事都在内存中存在,可以事先使用class_exists()函数来判定是否存在,存在就不用加载,不存在才加载

    <?php
    
    if(!class_exists('class_load')){
        //类不存在
        echo '类加载';
        include_once 'class_load.php';
    
    }
    $a=new info();
    var_dump($a);
    ?>

    3.自动加载:php没有那么只能得系统自动加载,所谓自动加载只是php提供了一种加载机制:即实现定义一个函数__autoload(),然后当系统需要使用类,而内存中有不存在的时候,系统就会自动调用__autoload()函数来加载类文件

    <?php
    //类文件
    //规定:要想实现自动加载,必须类名和文件名要相同
    class info{
    
    }
    
    ?>
    <?php
        //自动加载
        function __autoload($classname){
            //输出参数
            echo $classname;
            include_once $classname.'.php';
        }
    
    $a=new info();
    var_dump($a);
    ?>

    4.一个系统里,可能类文件会放到不同的路径下,因此一个完整的自动加载函数,应该要进行文件判定以及加载功能。

    <?php
        //自动加载
        function __autoload($classname){
         //假设当前文件目录下有c和m文件夹,里面有类文件
    
         //先尝试去c文件夹去找
         $c_file='c/'.$classname.'php';
         if(file_exists($c_file)){
            include_once $c_file;
            exit;
         }else{
             //尝试m文件夹找
             $m_file='m/'.$classname.'php';
             if(file_exists($m_file)){
                include_once $m_file;
                exit;
             }
         }
         
        }
    
    $a=new info();
    var_dump($a);
    ?>

    注意:自动加载是指按照开发者规定的路径去寻找对应的文件,并实现包含,如果文件不存在,那么系统会在使用类的时候报错,因为这是开发者自己犯的错,系统不能规范

    5.随着php版本的提升,在7以后,不怎么建议直接使用__autoload()函数,而是采用一种注册机制,将用户自定义的函数,放到系统内部,使用spl_autoload_register(定义好的函数)。

    本质与__autpload()一样。

    <?php
      //自定义函数,用来加载类文件,也需要一个参数来接收要加载的类名字
      function my_autoload($val){
            //功能与autoload()一样
            $c_file='c/'.$val.'php';
            if(file_exists($c_file)){
                include_once $c_file;
            }else{
                //说明c盘符没有对应的文件
                $m_file='m/'.$m_file.'php';
                include_once $m_file;
            }
      }
    
    
      //此时,上述函数永远不会自动执行,除非将函数注册到系统内部
     spl_autoload_register('my_autoload');
    
    
    
    $a=new info();
    var_dump($a);
    ?>

    注意:该方式其实本质就是通过两步完成了__autoload()一步操作,但是spl_autoload_register()函数可以注册多个自定义的加载函数,更方便管理

    总结:

      类的使用必须先保证内存中该类存在

      可以使用手动加载来确保类的使用安全,优点是明确,缺点是繁琐(类文件名可以随意没有规范)

      可以使用自动加载来让系统按照开发者设定的路径和方式去寻找类,并尝试加载到内存,(尽量让类文件名字统一,保证类名和文件名有关联)

      自动加载可以使用__autoload()函数来实现,也可以使用自定义函数+spl_autoload_register()注册共同实现(推荐使用这个)

      基本上所有的框架都在使用自动加载机制

  • 相关阅读:
    java学习day03-循环结构
    java学习day03-运算符+分支结构
    java学习day02-标识符+关键字+注释+变量
    java学习day02-数据类型
    java学习day01-认识Java语言Hello world!
    私有仓库
    服务编排
    镜像原理
    docker部署应用
    docker数据卷和数据卷容器
  • 原文地址:https://www.cnblogs.com/xiaowie/p/12197051.html
Copyright © 2011-2022 走看看