• php面向对象


    1. 面向对象典型例子

    //一个典型的类
    class Person{
        //注意这里用var定义,未确定用哪个关键词(protected,private,public)来修饰
        var $name ;
     
        //构造函数,
        function __construct($name){
            //通过构造函数传参来给类中的属性赋值
            $this->name = $name;
        }
        
        //说话这个方法
        function say(){
            echo "我的名字是".$this->name;
    }
    
    //实例化类.实例化后人就有了自己的专有特征,下面三个实例是不同的
    $people1 = new Person("王王","男",20);
    $people2 = new Person("李李","女",21);
    $people3 = new Person("张张","男",22);
    
    //每个具体的人都有自己的说法方式,能说出不同的内容
    $people1->say() //我的名字是王王
    $people2->say() //我的名字是李李
    $people3->say() //我的名字是张张
    
    

    总结:

    1. 一个类,可以有自己的属性,自己的方法,我们可以在构造函数中实现很多方法
    2. 实例化类是用new关键字,并且可以传入参数
    3. 访问这个实例化后的具体对象的方法是: 对象->属性 =xxxx
    4. 类和对象就像是,图纸和房子的关系,我们按照图纸施工就得到了一个有血有肉的真实的房子.这个过程就像是实例化,实例化后我们就可以在房子里做饭,洗衣服...

    2. $this关键字

    1. $this在构造函数中指代该构造函数所创建的新对象,就是指当前对象
    2. 在当前类中使用属性和方法, $this->属性 或者 $this->方法
    3. 对象的方法内的局部变量,只在当前方法内有效,所以不使用$this关键字,直接使用
    4. 局部变量和类的属性要认清,可以同名,但是要注意区分,尽量不同名,以免混淆
    class Person{
    
        var $name = "李四" ;
     
        function say($name){
            echo "我是类的属性中的name".$this->name;   
            echo "我是say方法中传递过来的参数".$name; 
            $this->dacnce();  //同样我们可以在say方法中调用person类中的dance方法;
        }
        
        function dance(){
            echo "我会跳霹雳舞";
        }
    }
    
    $people = new Person();
    $people->say('张三');
    //注意这里和上面例子中的区别,上面是在人实例化的时候就传入了初始属性,这里是给人的方法传入参数,注意理解
    
    

    3. $parent关键字

    1. parent用来引用父类的方法
    2. parent::的追溯不仅于直接父类
    ## 一.子类继承父类
    ## 例子1
    //父类
    class employee{
        protected  $sal=3000;
        public function getSal(){
            $this->sal = $this->sal + 1200;
            return $this->sal ; 
        }
    }
    //子类对父类继承
    class Manager extends employee {
        public function getSal(){
            // 这里调用了父类的方法,
            parent::getSal();
            //employee类中的return $this->sal 是为echo服务的
            //下面的$this->sal中的sal是通过继承得到的,而不是return回来的
            $this->sal = $this->sal + 1500;
            return $this->sal ;
        }
    }
    $emp = new employee();
    echo "普通员工的工资是 " . $emp->getSal();
    
    $manager = new Manager();
    echo "经理的工资是: " . $manager->getSal();
    
    //普通员工的工资是 4200
    //经理的工资是: 5700
    
    ## 二.子类对父类属性重写
    
    ## 例子2.1
    //父类的private属性不能被继承,如果父类有私有属性,那么父类的的方法只为父类的私有属性服务
    //父类 private $sal =3000
    //子类 protected $sal = 5000
    
    class employee{
        private  $sal=3000;
        public function getSal(){
            return $this->sal ;
        }
    }
    
    class Manager extends employee {
        protected  $sal=5000;
        
        public function getParentSal(){
            return parent::getSal();
        }
    }
    
    
    $manager = new Manager();
    //子类并且有getsal方法,这个方法是子类继承了父类的getsal方法,但是父类的私有属性$sal并没有被继承,这个被继承的父类getsal方法还是为父类的私有属性$sal服务,而不为子类的$sal服务
    echo $manager->getSal();  
    
    echo $manager->getParentSal();
    
    //输出结果是  3000    3000
    
    ## 例子2.2 
    //子类将父类的属性重写的情况下
    //父类 protected $sal =3000
    //子类 protected $sal = 5000
    
    class employee{
        protected  $sal=3000;
        public function getSal(){
            return $this->sal ;
        }
    }
    
    class Manager extends employee {
        protected  $sal=5000;
        
        public function getParentSal(){
            return parent::getSal();
        }
    }
    
    
    $manager = new Manager();
    echo $manager->getSal();  
    echo $manager->getParentSal();
    
    //输出结果是  5000    5000
    
    ## 三.子类对父类方法重写
    
    //子类重写的方法对当前private有效
    
    class employee{
        private  $sal=3000;
        public function getSal(){
            return $this->sal ;
        }
    }
    
    class Manager extends employee {
        private  $sal=5000;
        //重写父类的方法
        public function getSal(){
            return $this->sal ;   //这里返回的是子类的private属性
        }
        
        public function getParentSal(){
            //这里返回的是父类的priavte属性
            return parent::getSal();
        }
    }
    
    
    $manager = new Manager();
    echo $manager->getSal();  
    echo $manager->getParentSal();
    
    //输出结果是  5000    3000
    

    4. static关键字

    1. static关键字用来修饰属性和方法
    2. static关键字不经过实例化就能使用,不根据实例的不同而改变
    3. 静态属性在内存中只有一份,为所有实例共用
    4. 使用方法是 类名::静态属性 类名::静态方法名 或者 使用self::调用当前类中的其它静态方法
    5. 静态方法不能调用非静态属性(也就是不能用$this关键字来调用非静态属性,更不能用self:非静态属性这种错误的方式调用)

    5. const修饰

    1. const用来修饰常量,使用方法和静态属性一样 类名::常量名
    2. 常量不能被修改,修改会报错
    3. 常量要大写

    6. final关键字

    final关键字用于类和方法之前,final类不可以被继承,final方法不可以被覆盖(重写)

    7. 抽象方法和抽象类

    1. abstract修饰一个类和方法

    2. 抽象类不能被实例化,实例化会报错

    3. 子类(非抽象类)继承父类(抽象类),这时候子类是可以被实例化的,不会报错

    4. 抽象类继承抽象类的话,不需要重写其中的抽象方法,但是此时子类仍然不能被实例化

    5. 抽象类继承抽象类目的是对抽象类进行扩展

    6. 抽象方法只有声明,没有具体的实现方法

    7. 抽象方法没有{},而是采用;结束

    8. 抽象方法在子类中必须被重写,如果不重写就会报错,同时要注意参数的个数.如果父类中没有抽象方法,子类继承的时候不重写也不会报错

    9. 如果有抽象方法,当前类必须被声明为抽象类(但是抽象类中可以有非抽象方法)

    abstract class User{
        protexted $sal = 0;
        abstract function getSal();   //注意这里没有{}
    }
    

    8. 接口的定义和规范

    1. 接口是一种特殊的抽象类,只包含抽象方法和静态常量,没有其他类型的内容
    2. 接口的写法 : interface 接口名{}
    3. 接口抽象方法只能用public修饰,默认也是public权限,即使是final和abstract也不行
    4. 注意其他抽象方法是用abstract修饰的,这里不用,只需写法一直就可以了
    5. 接口中的静态常量就是用const修饰的就是了
    interface User{
        function getName();  //这是个抽象方法,最后是以 ; 结束的
        //function getAge(){};  //注意这是个非抽象方法,这样会报错的
    }
    

    9. 接口的实现

    1. 接口实现使用implements
    2. 一个类可以实现多个接口(解决了php单继承问题)
    3. 同抽象类的继承一样,实现接口要实现其中的抽象方法,否则会报错
    class Student{
        protect $grade ;
        public function getGrade(){
            return $this->grade;
        }
    }
    
    interface User{
        function getName();
    }
    
    interface Administrator{
        function setBulletin($_bulletin);
    }
    
    //可以一次实现多个接口
    class Admin implements User,Administrator{
        function getName(){}
        function setBulletin($_bulletin){}
    }
    
    //可以实现继承并且实现多个接口
    class Admin extend Student implements User,Administrator{
        function getName(){}
        function setBulletin($_bulletin){}
    }
    

    10. 多态

    1. 多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息将可以产生不同的结果,这种现象称为多态性
    2. 同一个操作作用于不同的类的实例,将产生不同的执行结果。也即不同类的对象收到相同的消息时,将得到不同的结果

    11. 接口的作用

    1. 继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的
    2. 接口用于描述一组类的公共方法/公共属性.它不实现任何的方法或属性,只是告诉继承它的类《至少》要实现哪些功能,继承它的类可以增加自己的方法.
    3. 使用接口可以使继承它的类: 命名统一/规范,易于维护
    4. 提供永远的接口。 当类增加时,现有接口方法能够满足继承类中的大多数方法,没必要重新给新类设计一组方法,也节省了代码,提高了开发效率.
    # 下面是一个关于usb接口的例子
    //首先定义一个usb接口
    interface USB{
    
        public function run();
    }
    
    # 下面定义三个不同的类key,mouse,store,都实现了上面的接口
    //键盘
    class key implements USB{
        
        public function run(){
            $this -> init();
        }
    
        public function init(){
            echo "key running ..";
        }
    }
    //鼠标
    class mouse implements USB{
    
        public function run(){
            $this -> init();
        }
    
        public function init(){
            echo "mouse running ...";
        }
    }
    //移动硬盘
    class store implements USB{
        
        public function run(){
            $this -> initialize();
        }
    
        private function initialize(){
            echo "store running ..";
        }
    }
    
    //以上三种设备都要遵循接口的run方法
    
    
    # 下面实现多态
    
    //1.首先我们可以
    $key = new key();
    $Key->run();
    
    $mouse = new mouse();
    $mouse->run();
    
    //上调用不同的类的相同名方法,会输出不同的东东,也就是说每个类里面的同名方法完成的功能可以是完全不同的
    
    //2.我们可以更进一步,用多态实现其调用
    
    class computer{
        public function useUSB($obj){
            $obj -> run();
        }
    }
    
    //实例化computer
    $computer = new computer();
    
    //给这个实例传入不同的对象(对象是根据接口实现的)
    $computer -> useUSB(new mouse()); 
    $computer -> useUSB(new store());
    $computer -> useUSB(new key());
    
    //3.再进一步,此时我们又有个声卡设备,
    //如果按照传统的方式,我们需要创建声卡类并实现接口,然后实例化声卡类,调用声卡方法,没增加一种设备,就要多一种调用方法,多了就不容易维护了
    //现在我们如果有了上面的方法,只需要创建新的声卡类,然后调用的时候还是使用computer中的useUSB方法,就可以了,这样看起来更容易维护,更容易扩展
    
    

    12. 对象克隆 __clone()方法

    1. 在项目中,使用两个或多个一样的对象,重新new关键对象,并且赋予相同的属性,是比较繁琐的
    2. 使用__clone()方法,可以得到两个一模一样的对象,并且互相不干扰
    3. __clone方法中有this和that指针
    class Person{
    
        var $name;
        var $age;
        
         //构造函数,
        function __construct($name='',$age=''){
            //通过构造函数传参来给类中的属性赋值
            $this->name = $name;
            $this->age = $age;
        }
     
        function say(){
           echo "我的名字是".$this->name;
           echo ",年龄是".$this->name;
        }
        
        function __clone(){
            //注意这里的this和that指针,$this指向复本people2,$that指向原本people1
            $this->name = "我是假的$that->name";
            $this->age = 30;
        }
    }
    
    $people1 = new Person("张三",20);
    $people2 = clone $people1;
    $people1->say();
    $people2->say();
    
    //结果:
    //我的名字是张三,年龄是20
    //我的名字是假的张三,年龄格式30
    

    13. call方法

    1. 当我们调用的方法在对象内容不存在时候,会出错,并停止运行程序
    2. 我们可以使用call方法来弹出一个提示说此方法不存在,然后程序可以继续执行
    class Test{
    
        //调用不存在的方法时候自动调用次方法,第一个参数是方法名,第二个参数是数组参数
        public function __call($methodName, $args){
            //我们可以在这里写一些处理逻辑
            print_r($args);
            echo "您传入的方法不存在";
        } 
    }
    
    $test = new Test();
    $test->demo("one","two","three",)   //因为demo方法并不存在,所以会自动调用上面的__call方法
    
  • 相关阅读:
    编写更好的CSS
    EntityFramework中支持BulkInsert扩展
    NoSql数据库使用
    jsoneditor显示Json data
    资源
    了解你的被测系统(why?)
    SQL SERVER开窗函数
    oracle中的exists 和not exists 用法详解(转)
    visualvm监控jvm及远程jvm监控方法(转)
    爆:中国互联网的那些黑色产业链(转)
  • 原文地址:https://www.cnblogs.com/redirect/p/10209063.html
Copyright © 2020-2023  润新知