美文网首页
Php的面向对象

Php的面向对象

作者: 做梦枯岛醒 | 来源:发表于2017-08-11 15:10 被阅读14次

    编程的艺术就是处理复杂性的艺术
    ----------------- Edsger Dijkstra

    面向对象的核心内容就是一切事物皆为对象。
    第一次接触面向对象的时候是java,面向对象主要的特点就是封装,继承和多态。对于面向对象的概念我也不必多说,这里我只记录一下php的面向对象的使用方法。

    类的声明

    和各种语言一样php也是通过class来声明类的
    那么声明类需要几个注意

    • 权限修饰符是可选项(public protected private 或者省略)
    • class是创建类的关键字
    • 类名是所需要创建类的名称,在class之后,后面是{}
    • 类体必须放在{}里

    下面是一个简单的类的声明,包括一个构造方法和一些getter和setter方法

    <?php
    
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/10
     * Time: 21:15
     */
    class student
    {
      var $name;
      var $age;
      var $sex;
    
        /**
         * student constructor.
         * @param $name
         * @param $age
         * @param $sex
         */
        public function __construct($name, $age, $sex)
        {
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }
    
        /**
         * @return mixed
         */
        public function getName()
        {
            return $this->name;
        }
    
        /**
         * @param mixed $name
         */
        public function setName($name)
        {
            $this->name = $name;
        }
    
        /**
         * @return mixed
         */
        public function getAge()
        {
            return $this->age;
        }
    
        /**
         * @param mixed $age
         */
        public function setAge($age)
        {
            $this->age = $age;
        }
    
        /**
         * @return mixed
         */
        public function getSex()
        {
            return $this->sex;
        }
    
        /**
         * @param mixed $sex
         */
        public function setSex($sex)
        {
            $this->sex = $sex;
        }
        
    }
    

    下面是一个测试的文件

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/10
     * Time: 21:19
     */
    
    //注意在这个地方,需要引用这个类文件(php的类要带个.class.php的后缀)
    require_once 'Student.class.php';
    echo "下面创建一个student对象";
    //初始化
    $stu = new Student("surine",12,"boy");
    //使用
    echo $stu->getName();
    echo $stu->sex;
    

    除了注意这个类需要手动引入之外其他的都很简单,和java的类似。

    特殊访问方式

    1.$this

    this这个用法我们在java里也经常用,作用就是完成对象内部成员之间的访问。

    2.::

    相比this,::才是真正的强大,他可以在没有任何实例的情况下来访问类成员

    那么他的格式如下

    关键字::变量名/常量名/方法名
    

    这里的关键字分为下面几种情况

    1. parent : 调用父类的相关成员 (相当于java的super)
    2. self:调用当前类的静态成员和常量
    3. 类名:调用本类的变量常量和方法。
    

    下面是一个演示

    <?php
    class animal{
        const NMAE = "动物";
    
        /**
         * animal constructor.
         */
        public function __construct()
        {
            //使用类名访问常量成员
            echo "动物类:".animal::NMAE;
        }
    }
    
    class Cat extends animal{
        const NMAE = "猫";
    
        /**
         * Cat constructor.
         */
        public function __construct()
        {
            echo "<br>";
            //使用parent访问父类构造
            echo parent::__construct();
            echo "<br>";
            //使用self访问自身常量成员
            echo self::NMAE;
            echo "<br>";
        }
    }
       echo "类外调用:".Cat::NMAE;
       new Cat();
    

    运行结果:

    运行结果PNG

    构造和析构

    构造函数大家都知道,在面向对象语言中起着初始化的作用,php也不例外,java中构造函数必须和类同名,php也可以这样写,但是更常见的是下面这种写法

     public function __construct()
        {
            //注意construct前面是两个下划线
        }
    

    我们知道java等语言构造方法是可以有多个的,我们称之为重载,但是php不允许这样,他通过默认参数来实现重载,我们可以给参数赋值,也可以不用这样达到了同样的一个效果。

    那么我们同样知道析构函数是在对象销毁的时候执行的一个方法

     function __destruct()
        {
            // TODO: Implement __destruct() method.
        }
    

    通常在析构方法里做一些释放资源的任务。

    封装

    这是面向对象的三大特点之一,封装的意思就是抽象一个类,包含一些属性,那么这些属性或者方法都有访问权限,比如说public,private,protected

    继承

    继承使得面向对象更加灵活,我们可以通过extends关键字来实现一个类的继承,在前面我也演示过,并且我们知道通过parent::来访问父类的方法

    多态

    多态顾名思义就是有多种状态,包括重载重写等
    下面是一个通过接口(接口在下面讲到)实现的多态

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/11
     * Time: 14:26
     */
    interface Type{
        public function go_Type();
    }
    class Type_car implements Type{
    
        public function go_Type()
        {
            echo "car";
            // TODO: Implement go_Type() method.
        }
    }
    
    class Type_bus implements Type{
    
        public function go_Type()
        {
            echo "bus";
            // TODO: Implement go_Type() method.
        }
    }
    
    function change($obj){
        if($obj instanceof Type){
            $obj->go_Type();
        }else{
            echo "obj不合法";
        }
    }
    change(new Type_car());
    

    那么这个当然是输出car。

    抽象

    抽象类是不能被实例化的特殊类,他是配合多态使用的,只能作为其他类的父类,使用abstract来声明

    那么抽象类和普通类相似,包括成员变量和成员方法,两者区别在于,抽象类至少要包含一个抽象方法,那这个方法是没有方法体,他的方法体是在子类中实现的。

    例如:

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/11
     * Time: 14:11
     */
    abstract class animal{
        abstract function run();
        abstract function eat();
    }
    
    class cat extends animal{
    
        //必须实现其方法
        function run()
        {
            // TODO: Implement run() method.
            echo "run()";
        }
    
        function eat()
        {
            // TODO: Implement eat() method.
           echo "eat()";
        }
    }
    
    $cat = new Cat();
    //调用
    $cat->eat();
    

    我们抽象一个动物方法,然后用cat类继承自它,实现其中的相关方法,然后我们可以通过对象进行调用。

    接口

    继承增加了类的复用性,但php和java类似也只支持单继承,那么多继承当然是使用接口实现。

    接口声明如下

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/11
     * Time: 14:17
     */
    interface One{
        const CON = "value";
        function One();
    }
    
    interface Two extends One{
        function Two();
    }
    

    可以看到php的接口也是interface声明,而且也支持extends
    那么接口怎么使用?

    require_once "MyInter.php";
    class TestInter implements One,Two{
        public function One(){
          echo "one";
        }
        public function Two(){
            echo "two";
        }
    }
    $test = new TestInter();
    $test->Two();
    

    输出结果就是two

    其他关键字

    1.final

    final意思是最终的,最后的,也就是最终版本,不允许做其他修改,如果有个类用final修饰,那么他一定不会有子类,不会被继承

    2.static

    static就是静态的意思,在java中也是有的,他属于类本身,但是不属于类的任何实例,它相当于储存在类中的全局变量,那么同样我们可以使用::访问

    魔术方法

    php中有很多以__开头的方法,比如说构造,析构,这些方法被称为魔术方法,那么下面是几个魔术方法

    1.__get() __set()

    这是php的getter和setter,用于赋值获取值,为外部提供的访问接口

    2.__isset() __unset()

    这个函数类似于isset和unset函数,如果对象中存在__isset()方法,当在类的外部使用isset函数检测对象中的私有成员属性时,就会自动调用类中的__isset()方法完成对私有成员属性的检测操作
    __unset()函数是删除指定的变量,参数为要删除的变量名称

    3.__call()

    这个函数的作用是:当对象企图使用一个不存在的方法时,系统就会调用call函数,并且把方法名和参数都记录下来。
    下面是一个例子

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/11
     * Time: 14:43
     */
    class Call{
        var $a;
    
        /**
         * Call constructor.
         * @param $a
         */
        public function __construct($a)
        {
            $this->a = $a;
        }
    
        /**
         * @return mixed
         */
        public function getA()
        {
            return $this->a;
        }
    
        /**
         * @param mixed $a
         */
        public function setA($a)
        {
            $this->a = $a;
        }
    
        function __call($name, $arguments)
        {
            echo $name;
            echo "<br>";
            print_r($arguments);
            // TODO: Implement __call() method.
        }
    }
    
    $a = new Call(10);
    $a->A("???");
    

    可以看到我们最后调用了A这个方法,这个方法其实是不存在的,系统识别到,并调用了__cal方法,输出结果就是call方法体里的内容

    call.PNG
    4.__toString()

    这个方法在java中也见过,那么我们可以这样使用它

    //在类里实现它
    function __toString()
      {
          return "我是方法";
          // TODO: Implement __toString() method.
      }
    
    //直接打印对象
    echo $a; 
    

    得到的结果就是执行了__toString输出的内容。
    如果没有这个方法将会发生致命错误

    5.__autoload()

    可以看到我们在之前的类导入的时候都是手动require的,这样比较麻烦也比较乱。
    那么系统为我们提供了自动导入的方法,下面一个小例子演示一下

    <?php
    /**
     * Created by PhpStorm.
     * User: surine
     * Date: 2017/8/11
     * Time: 14:55
     */
    function __autoload($name){
        $file = realpath(__DIR__).'/'.$name.'.php';
        if(file_exists($file))
        {
            require_once($file);
           if(class_exists($name,false))
           {
               return true;
           }
            return false;
        }
        return false;
    }
    $test = new Call();
    $test->getA();
    

    在未实例化之前系统首先判断存不存在这个文件,然后确定导入之后才能实例化。

    总结

    当然面向对象不止这点东西,更多更有意思的东西在以后学习过程中研究。

    相关文章

      网友评论

          本文标题:Php的面向对象

          本文链接:https://www.haomeiwen.com/subject/anfkrxtx.html