zoukankan      html  css  js  c++  java
  • PHP面试 PHP基础知识 九(面向对象)

    面向对象

      PHP的类权限控制修饰符

        public(公共的) 、 protected(受保护的)、private(私有的)

        public :最高权限   可以在类的内部使用  可以在类的外部使用  可以在子类中使用

        protected:可以在类的内部使用   可以在子类当中使用

        private:只能在类的内部使用   不可以被继承  不可以在类的外部使用

      面向对象的封装、继承、多态

        封装:成员访问权限   public  protected  private 访问权限问题

        继承:单一继承    同时只能继承一个类

            方法重写  子类继承一个父类   在子类中写一个于父类相同的方法名会把父类的方法覆盖掉

           如果不想覆盖可以使用parent先调用一下父类的方法

    class  Father{
          public function test(){
           }  
    }        
    
    class Son extends Father{
          public function test(){
             
              parent::test();
               
               .....
          }
    }    

         多态:

          抽象类的定义

    抽象类定义前面以abstract关键字开始  
    类中可以定义多个方法,可以具体实现方法,也可定义抽象方法,抽象方法就是没有绝体实现的方法,需要在方法前加 abstract 关键字,抽象方法需要在子类中实现
    类中只要有抽象方法,这个类必须定义为抽象类。
    抽象类和接口一样不能直接实例化为对象,只能被普通类继承。
    
    定义一个抽象类
    abstract class MyList{
           
           //抽象方法需要在子类中实现
           abstract  public function  selectgroup($where);
    
           public function del($where){
    
                echo  "删除成功";
    
           }
    }
    
    //Tag类继承MyList抽象类
    class  Tag extends MyList{
            //实现抽象方法
            public   function selectgroup(){
             
                 echo "查找数据";
    
           }
    
    } 
    
    //Plist类继承MyList抽象类
    class Plist extends MyList{
            //实现抽象方法
            public  function selectgroup(){
            
                   echo  "查找数据库";      
      
            }
    
    }

          接口的定义    interface 声明定义接口     一句话说明:类方法必须实现,接口的方法必须为空

            不同类的共同方法在接口中定义,然后在不同类中实现不同的功能

            接口本身就是抽象的不用加  abstract

            一个类可以一次实现多个接口   语法用implements实现

            接口可以被继承 用extends

            接口定义方法只能使用public

            接口不能创建自己的对象   

    interface Action(){
           
           public function eat($foods);  
    
    }
    
    
    
    //普通类实现接口方法
    
    calss Human implements Action(){
        
           //实现接口必须提供接口中的方法
       
           public  function eat($foods){
          
                  echo "Human eat";
           }
        
    }    
    
    class  Animal implements Action(){ 
    
              public function eat( $foods){ 
    
                  echo "Animal eat {$foods}"; 
              
               }
    
    }
    
    //调用完成的方法
    $human = new Human(); 
    
    $human->eat(); 
    
     
    $animal = new Animal(); 
    
    $animal->eat(); 
    
    
    ///   instanceof 判断某个对象是否实现了某个接口
    
    function CheckEat( $obj ){ 
    
        if(     $obj instanceof Action  ){ 
    
            $obj->eat(  'orange' ); 
    
        }else{ 
    
            echo "the object not implements Action"; 
    
        } 
    
    } 
    
    CheckEat( $human ); 
    
    CheckEat( $animal );
    
    
    //接口继承
    
    //extends 让接口继承接口 
    
    interface IcanPee  extends Action(){ 
    
       public function pee(); 
    
    } 
    
     
    
    //当类实现子接口时,父接口定义的方法也需要在这个类里面具体实现 
    
    Class Human1 implements IcanPee(){ 
    
       public function pee(){  } 
    
       public function eat( $foods ){  } 
    
    } 
      魔术方法

      __construct()    构建对象时使用

      __destruct()      明确销毁对象或脚本结束时被调用

      __call()              调用不可访问或不存的方法时被调用

       __callStatic()    调用不可访问或不存在的静态方法时被调用

      __get()               读取不可访问或不存在的属性时被调用

      __set()                当给不可访问或不存在的属性赋值时被调用

      __isset()              对不可访问或不存在的属性调用isset()或empty()时被调用

      __unset()             对不可访问或不存在的属性进行unset时被调用

      __sleep()             当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用

      __wakeup()          当使用unserialize时被调用,可用于做些对象的初始化操作

      __toString()          当一个类被转换成字符串时被调用

      __clone()              进行对象clone时被调用   用来调整对象的克隆行为

      __invoke()             当以函数方式调用对象时被调用

        __set_state()          当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值

      __debuginfo()        当调用var_dump()打印对象时被调用(不想打印所有属性)PHP5.6版本

    class MyExample{
          
          public $var = 'test';
          
         //构造函数
          public   function   __construct()
          {
                echo  '__contruct'.PHP_EOL;
          }
         
         //对象的引用都被删除、对象被销毁、调用exit()后、脚本关闭时被调用
      public   function   __destruct()
          {
                echo '__destruct'.PHP_EOL;
          }
         
         //调用不可访问或不存在的方法时被调用
      public   function  __call($name, $arguments)
          {
                echo '__call'.PHP_EOL;
          } 
          
          //调用不可访问或不存在的静态方法时被调用
      public  static  function  __callStatic($name, $arguments)
         {
                  echo '__callStatic'.PHP_EOL;
         }
    
         //读取不可访问或不存在的属性时被调用
      public  function  __get($name)
         {
                  echo '__get'.PHP_EOL;
         }
         
         //不可访问或不存在的属性赋值时调用
          public   function   __set($name, $value)
          {
                  echo '__set'.PHP_EOL;
          }
    
          //不可访问或不存在的属性调用isset()或empty()时被调用
      public  function   __isset($name)
          {
                  echo '__isset'.PHP_EOL;
          }
          
          //不可访问或不存在的属性unset时被调用
      public   function  __unset($name)
         {
                  echo '__unset'.PHP_EOL;
          }
    
          //serialize时被调用 ,不需要保存大对象的所有数据时有用
      public   function   __sleep()
         {
               echo '__sleep'.PHP_EOL;
               return array('var111111111111111');
         }
    
          //unserialize时被调用,可用于做些对象的初始化操作
      public   function  __wakeup()
         {
                echo '__wakeup'.PHP_EOL;
                $this->var = 'test after wakeup';
         }
    
         //一个类被转换为字符串时被调用
      public   function __toString()
         {
                 return '__toString'.PHP_EOL;
         }
    
         //进行对象clone时被调用   用来调整对象的克隆行为
      public   function  __clone()
         {
                echo '__clone'.PHP_EOL;
         }
         
         //以函数方式调用对象时被调用
         public  function  __invoke()
         {
                 echo '__invoke'.PHP_EOL;
         }
    
         //当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。
         public  static  function __set_state($arr)
        {
                return  '__set_state'.PHP_EOL;
        }
        
        //调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本
        public function __debuginfo()
        {
                echo '__debuginfo'.PHP_EOL;
                return array(
                               'var' =>'test fro __debuginfo'
                           );
        }
    
    }  
    
    $m = new MyExample();        //__construct()被调用
    $m->not_exist_property = test;    //__set()被调用
    echo $m->not_exist_property;    //__get()被调用
    $m->abc(1,2,3);       //__call()被调用
    echo isset($m->not_exist_property);   //__isset()被调用,返回bool值
    unset($m->not_exist_property); //__unset()被调用
    echo $tmp = serialize($m); //__sleep()被调用
    unserialize($tmp); //__wakeup()被调用
    $m1 = clone $m; //__clone()被调用,对象默认是引用传递,使用clone关键词则可实现对象复制
    $m();     //__invoke()
    eval( '$m2 = '  .  var_export ( $m ,  true ) .  ';');var_dump($m2);
    var_dump($m);
    //最后__destruct()被调用
      设计模式

        常见的设计模式:工厂模式、单例模式、注册树模式、适配器模式、观察者模式、策略模式

      工厂模式

        工厂模式是最常用的实例化对象模式,使用工厂方法代替new操作的一种模式

        工厂模式的好处是,你想要更改所实例化的类名等,则只需要更改工厂方法内容即可,不需逐一寻找代码中具体实例化的地方修改。为系统结构提供了灵活的动态扩展机制,减少耦合。

    /**
     *简单工厂模式(静态工厂方法模式)
     */
    /**
     * Interface people 人类
     */
    interface  people
    {
        public function  say();
    }
    /**
     * Class man 继承people的男人类
     */
    class man implements people
    {
        // 具体实现people的say方法
        public function say()
        {
            echo '我是男人<br>';
        }
    }
    /**
     * Class women 继承people的女人类
     */
    class women implements people
    {
        // 具体实现people的say方法
        public function say()
        {
            echo '我是女人<br>';
        }
    }
    /**
     * Class SimpleFactoty 工厂类
     */
    class SimpleFactoty
    {
        // 简单工厂里的静态方法-用于创建男人对象
        static function createMan()
        {
            return new man();
        }
        // 简单工厂里的静态方法-用于创建女人对象
        static function createWomen()
        {
            return new women();
        }
    }
    /**
     * 具体调用
     */
    $man = SimpleFactoty::createMan();
    $man->say();
    $woman = SimpleFactoty::createWomen();
    $woman->say();
      单例模式

        单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

        单例模式一种常见的设计模式。比如用于,线程池、缓存、日志对象、对话框、打印机、数据库操作等。

        单例模式分为三种:懒汉式单例、饿汉式单例、登记式单例。

        有三个特点:

          1、只能有一个实例。

          2、必须自行创建这个实例

          3、必须给其他对象提供这一实例

        为什么要使用单例模式?

        PHP一个主要应用场合就是引用程序和数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库连接数据库行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗和内存的资源。

    class Single {
        private $name;//声明一个私有的实例变量
        private function __construct(){//声明私有构造方法为了防止外部代码使用new来创建对象。
        }
        static public $instance;//声明一个静态变量(保存在类中唯一的一个实例)
            static public function getinstance(){//声明一个getinstance()静态方法,用于检测是否有实例对象
            if(!self::$instance) self::$instance = new self();
                return self::$instance;
        }
        public function setname($n){ $this->name = $n; }
            public function getname(){ return $this->name; }
    }
    $oa = Single::getinstance();
    $ob = Single::getinstance();
    $oa->setname('hello world');
    $ob->setname('good morning');
    echo $oa->getname();//good morning
    echo $ob->getname();//good morning
      注册模式

        注册模式,解决全局共享和交换对象。已经创建好的对象,挂在某个全局可以是哟个的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局树上,任何地方直接去访问。

    class Register
    {
        protected static  $objects;
            function set($alias,$object)//将对象注册到全局的树上
            {
                self::$objects[$alias]=$object;//将对象放到树上
            }
            static function get($name){
            return self::$objects[$name];//获取某个注册到树上的对象
        }
        function _unset($alias)
      {
            unset(self::$objects[$alias]);//移除某个注册到树上的对象。
        }
    }
      适配器模式

        将各种截然不同的函数接口封装成统一的API

        PHP中的数据库操作有MySQL、MySQLi、PDO三种,可以使用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。

        首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。

    //接口  IDatanase
    interface IDatabase
    {
        function connect($host, $user, $passwd, $dbname);
        function query($sql);
        function close();
    }
    
    //   Mysql
    class MySQL implements IDatabase
    {
        protected $conn;
            function connect($host, $user, $passwd, $dbname)
            {
                $conn = mysql_connect($host, $user, $passwd);
                mysql_select_db($dbname, $conn);
                $this->conn = $conn;
        }
        function query($sql)
            {
                $res = mysql_query($sql, $this->conn);
                return $res;
        }
        function close()
        {
            mysql_close($this->conn);
        }
    }
    
    //Mysqli
    class MySQLi implements IDatabase
    {
        protected $conn;
        function connect($host, $user, $passwd, $dbname)
        {
            $conn = mysqli_connect($host, $user, $passwd, $dbname);
            $this->conn = $conn;
        }
        function query($sql)
        {
            return mysqli_query($this->conn, $sql);
        }
        function close()
        {
            mysqli_close($this->conn);
        }
    }
      观察者模式

      1、观察者模式,当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。

      2、场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变的那一维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。

      3、观察者模式实现了低耦合,非侵入式的通知与更新机制。

    // 主题接口
    interface Subject{
        public function register(Observer $observer);
        public function notify();
    }
    
    // 观察者接口
    interface Observer{
        public function watch();
    }
    
    // 主题
    class Action implements Subject{
         public $_observers=array();
         public function register(Observer $observer){
             $this->_observers[]=$observer;
         }
    
         public function notify(){
             foreach ($this->_observers as $observer) {
                 $observer->watch();
             }
    
         }
     }
    
    // 观察者
    class Cat implements Observer{
         public function watch(){
             echo "Cat watches TV<hr/>";
         }
     } 
     class Dog implements Observer{
         public function watch(){
             echo "Dog watches TV<hr/>";
         }
     } 
     class People implements Observer{
         public function watch(){
             echo "People watches TV<hr/>";
         }
     }
    
    
    
    // 应用实例
    $action=new Action();
    $action->register(new Cat());
    $action->register(new People());
    $action->register(new Dog());
    $action->notify();
      策略模式

      策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择徐太的算法并使用。

      策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个模式本身的核心思想就是面向对象编程的多形性思想

      策略模式三个角色

         1:抽象策略角色

         2:具体策略角色

         3:环境角色(对抽象策略角色的引用)

      实现步骤:

         1:定义抽象角色类   (定义好各个实现的共同抽象方法)

         2:定义具体策略类     (具体实现父类的共同方法)

         3:定义环境角色类     (私有化申明抽象角色变量,重载构造方法,执行抽象方法)

      打个比方说明策略模式:

         如果我需要买衣服了,我可以有几种方式买衣服?

          1、我可以在京东购买。

          2、我可以在淘宝购买。

          3、我可以找代购买。

          4、我可以去商场买。

          每个方式我都可以买到衣服,但是使用了不同方式。

        abstract class baseAgent { //抽象策略类
            abstract function PrintPage();
        }
        //用于客户端是IE时调用的类(环境角色)
        class ieAgent extends baseAgent {
            function PrintPage() {
                return 'IE';
            }
        }
        //用于客户端不是IE时调用的类(环境角色)
        class otherAgent extends baseAgent {
            function PrintPage() {
                return 'not IE';
            }
        }
        class Browser { //具体策略角色
            public function call($object) {
                    return $object->PrintPage ();
                }
            }
            $bro = new Browser ();
        echo $bro->call ( new ieAgent () );
  • 相关阅读:
    跨域上传文件
    算法
    websocket
    Bottle
    爬虫一
    RabbitMQ
    git&github快速入门
    centos6安装SaltStack
    ajax
    Django之Model操作
  • 原文地址:https://www.cnblogs.com/dcrq/p/11059776.html
Copyright © 2011-2022 走看看