4面向对象

作者: 哈士奇大叔 | 来源:发表于2020-04-02 18:32 被阅读0次

    [TOC]

    面向对象

    1. 面向对象的基本概念

    1.1 什么是面向对象编程。

    准确的说面向对象编程我们叫 OOP.面向对象的编程分为三部分:面向对象分析(Object Oriented Analysis,OOA)、面向对象设计(Object Oriented Design,OOD),以及面向对象编程(Object Oriented Programming)。面向对象编程的两个中个重要的概念是类和对象。

    1.2. 类

    世间万物皆对象,万事万物皆对象。当然,这是在 js 当中的一个概念。在其他的编程语言当中,我们说时间万物都具有它自身的属性和方法,通过这些属性和方法,可以将不同的事物区分开来,这就是我们在座的面向对象类的抽象。例如,人具有身高。体重和肤色等等这些属性。还可以吃饭,学习走路可以做一些活动。这些活动就是人具有的功能。而前面所说的体重,肤色,身高等等这些是什么呢?是属性。所以我们就可以把人看作是程序当中的一个类。那么人的身高可以看做什么?可以看做类的属性走路啊,吃饭呀,可以看做类的方法。所以什么是类,类是属性和方法的集合.是面向对象编程最核心的东西。也是它的基础。所以通过类呢,我们可以将一些零散的用来去实现某一个功能的代码进行一些管理。比如说,我们可以创建一个运动类。爱运动类里面包括有这么些个属性姓名身高体重年龄。和性别,然后我再定义几个方法,他能踢足球,他能打篮球啊,能举重能跳高。能吃能玩。

    1.3. 对象

    类只是具备某项功能。一个抽象模型实际应用当中呢,我们需要使用的是对象。所以我们就需要从那当中去实例化出来这个对象,然后去使用这些对象。对象呢,是类进行实例化之后的一个产物。它是一个实体,是一个独立的个体。例如,我们仍然以人为例。"黄种人是人"这句话里边儿。没有错误对吧,但是反过来说 "人是黄种人",就有问题,因为除了黄种人,还有白人,黑人等就,这里的"黄种人"就是"人"这个类中的一个实例对象。

    1.4. 面向对象的三大特征

    面向对象编程的大大特征就是封装性,继承性,多态性

    1.4.1. 封装性

    封装性也可称之为信息隐藏,就是把一个类的使用和实现分开,只保留有限的接口(方法)与外部练习。同时也避免程序之间的 相互依赖而产生的不便。

    1.4.2. 继承性

    继承性就是派生类(子类)自动继承一个或多个基类(父类)中的属性与方法。并且我们可以重写和添加新的属性方法。可以简化对象和类的创建,提高代码的可复用性,继承分单继承和多继承。PHP 中支持的是单继承。一个子类有且只有一个父类。

    1.4.3. 多态性

    同一个类的不同对象,调用一个方法可以获得不同的结果。增强程序的灵活性和重用性。

    2. PHP 对象

    2.1. 类的定义

    和很多其他面向对象的语言一样,PHP 通过 class 关键字加类名来定义类。

    <?php
    class SportObject{
        // ----
    }
    ?>
    

    2.2. 成员方法

    类中的函数被称为成员方法,函数与成员方法唯一的区别就是函数实现的是某个独立的功能。而成员方法实现的是类的一个行为,它是类的其中一部分。
    关键字(修饰符) 成员方法

    <?php
    class SportObject{
        function bealBasketBall($name,$age,$height,$sex){
            echo $name.'<br>';
            echo $age.'<br>';
            echo $height.'<br>';
            // return ;
        }
    }
    ?>
    

    2.3. 类的实例化

    首先我们要实例化对象(通过 new 关键字 实例化对象),才能通过对象执行对应的行为方法。通过对象->成员方法 来调用成员方法。

    <?php
    class SportObject{
        function bealBasketBall($name,$age,$height,$sex){
            if($height>=180){
                return $name.'符合打篮球的身体素质要求!';
            }else{
                return $name.'不符合打篮球的身体素质要求!';
            }
        }
    }
    $s1=new SportObject();
    echo $s1->bealBasketBall('曾辉',20,170,'男');
    $s2=new SportObject();
    echo $s1->bealBasketBall('曾辉2号',40,181,'男');
    ?>
    

    2.4. 成员变量

    类中的变量,也称为成员变量。有些人也把它叫做属性或者字段。成员变量的是用来保存数据信息。或者与成员方法进行一些交互来实现某项功能。
    定义成员变量和成员方法:
    关键字(修饰符) 成员变量名

    关键字可以使用public ,private, protected, static 中的任意一个。
    

    访问成员变量和成员方法的方法一样,对象->成员变量

    class SportObject{
        // 声明成员变量。
        public $name;
        public $height;
        public $sex;
        public function boolFootBall($name,$height,$sex){
                return $name.'是个足球运动员';
        }
    }
    $s1=new SportObject;
    $s1->name='佚名';
    var_dump($s1);
    // $s1->boolFootBall('佚名');
    

    <table> <tr><td bgColor="orange"><strong>注: this-> 所用是调用本类中的 成员变量或成员方法。 无论使用的是"this->" 还是"对象名->"哪种格式,后面的变量名是没有$符号的.
    </strong></td></tr></table>

    2.5. 类常量

    常量是在程序运行期间,不可改变的量,我们说他是一个恒值,举例圆周率就是一个常量。定义常量,我们使用关键字 const。

    class SportObject{
        const SPORT_TYPE="体育运动";
        public $name;
        function setName($name){
            $this->name=$name;
        }
        function getName(){
            return $this->name;
        }
    }
    $s1=new SportObject;
    $s1->setName('aaa');
    echo $s1->getName().'<br>';
    echo $s1->name.'<br>';
    echo SportObject::SPORT_TYPE.'通过类::常量名';
    

    2.6 构造函数和析构函数

    2.6.1 构造函数

    当一个类实例化为一个对象的时候,可能可能会随着对象的初始化而初始化一些成员变量。就是给一些成员变量复制值。这种情况下我们就可以使用构造函数。因为咱对象实例化过程当中构造函数是自动执行的。

    class Person{
        public $name;
        public $age;
        public $sex;
        public $height;
        // 我们可以通过"__construct()"
        public function __construct(){
            echo '123';
        }
    }
    
    $p1=new Person;
    // 如果成员变量过多,写起来比较麻烦
    // $p1->name='aa';
    

    构造函数是在初始化对象时使用的,如果类中没有构造方法,PHP 会自动生成一个构造函数,自动生成的构造方法是没有参数的。

    2.6.2 析构函数

    析构函数的作用和构造方法方法刚好相反,是对象被销毁时被调用的,作用呢是释放内存。

    <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        public $height;
        // 我们可以通过"__construct()"
        // 构造函数
        public function __construct($name,$height,$age,$sex){
            // 为成员变量赋值。
            $this->name=$name;
            $this->height=$height;
            $this->age=$age;
            $this->sex=$sex;
            echo $this->sayHi();
        }
        public function sayHi(){
            return "你好,我叫$this->name ,我今年$this->age 岁了,身高$this->height,性别$this->sex";
        }
        // 析构函数
        public function __destruct(){
            echo '已经被释放掉了';
        }
    }
    $p2=new Person("佚名",180,23,'女');
    
    

    2.7 继承和多态

    其实继承和多态啊最根本的作用就是完成代码的重用。

    2.7.1 继承

    子类继承父类的所有成员变量方法,包括构造方法,当子类被实例化的时候,PHP 会先在子类当中找构造方法,如果子类已经有自己的构造方法。PHP 会先调用子类的方法。当子类当中没有的时候,PHP 才会去调用。父类当中的构造方法,这就是继承。

    // 父类(基类)
    class SportClass{
        // 定义成员变量
        public $name;//姓名
        public $age;//年龄
        public $weight;//体重
        public $sex;//性别
        public function __construct($name,$age,$weight,$sex){
            $this->name=$name;
            $this->age=$age;
            $this->weight=$weight;
            $this->sex=$sex;
        }
        function sayHi(){
            echo '你好,我是'.$this->name;
        }
    }
    
    /**子类(派生类)BealBasketBall*/
    class BealBasketBall extends SportClass{//定义子类,继承父类
        // 定义成员变量  身高
        public $height;
        public function __construct($name,$height){
            $this->height=$height;
            $this->name=$name;
        }  
        
        // function sayHi(){
        //     echo '你好,我是'.$this->name;
        // }
    }
    
    $b1=new BealBasketBall('曾辉',198);
    

    2.7.2 多态

    多态好比有一个成员,方法是让大家去游泳,这时有人带着游泳圈还有人拿着浮板。还有人什么也不带。虽然是同一种方法,但是却产生了不同的形态,这就叫多态。

    多态存在两种形式,覆盖和重载。
    1).所谓的覆盖,在子类中重写父类的方法。而在子类的对象当中,虽然调用的是父类当中相同的方法,但返回的结果是不一样的。你看啊,上面的那个例子当中都调用了父类当中的说明方法。但是返回的结果却不同。
    2).再就是重载,重载是类的多态的另外一种体现。函数在重载的时候会有一个标识符。被当做多个函数名称。而且呢,能够通过函数的参数的个数或者参数的类型,将这些同名的函数区分开来,(方法名称是相同的),可能是参数的数量或者参数的类型不同。以便于去使用和调用的时候不发生混淆。
    PHP所提供的重载(overloading)是指动态地创建类属性和方法。我们是通过魔术方法(magic methods)来实现的。

    class A{
        function __call($name,$num){
            echo "方法名称:".$name.'<br>';
            echo '参数存在的个数:'.count($num).'<br>';
            if(count($num)==1){
                echo $this->list1();
            }
            if(count($num)==2){
                echo $this->list2();
            }
        }
    
        public function list1($a){
            return "这是list1函数,:参数:$a";
        }
        public function list2($a,$b){
            return "这是list1函数,:参数1:$a ,参数2:$b ";
        }
    }
    
    $a=new A;
    $a->list(1);
    

    2.8 "$this->" 和"::"的使用

    PHP通过为变量"this->"和作用域操作符"::"来实现访问自己的成员变量和成员方法的。 **1.this->**
    在本类内部我们可以通过"this" 访问当前类实例化的对象。调用方法或成员变量的话,则使用"this->成员变量"||"this->成员方法" 来访问成员方法和变量。所以"this->"只在类的内部使用

    class Demo{
        function exam(){
            if(isset($this)){
                echo '$this的值:'.get_class($this);
            }else{
                echo '$this 未定义';
            }
        }
    }
    $d1=new Demo;
    $d1->exam();
    

    2. 操作符::
    $this只能在类的内部去使用。操作符"::"可以在没有声明任何实例的情况下,访问类当中的成员方法或成员变量。

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

    关键字有三种情况:

    • parent: 可以调用父类中的 成员变量,成员方法和常量
    • self:可以调用当前类中的 静态成员和常量
    • 类名:可以调用本类中的静态变量,常量和静态方法
    class A{
        const NAME_='A';
        public $name;
        public $age;
        public $sex;
        public function __construct($name,$age,$sex){
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    }
    
    class B extends A{
        const NAME_='B';
        public $height;
        public $weight;
        public function __construct($name,$age,$sex,$height,$weight){
            parent::__construct($name,$age,$sex);  
            $this->height=$height;
            $this->weight=$weight;
        }
        public function a(){
            self::NAME_;
            parent::NAME_;
        }
    }
    $b1=new B('姓名','年龄','xingbie','身高','体重');
    B::NAME_;
    

    2.9 修饰符

    public、private、protected、static和final。这些关键字是用来限定类成员(包括方法和变量)的访问权限。

    2.9.1 public(公共成员)

    顾名思义就是可以公开的,没有必要去隐藏的一些数据信息。可以用public来去修饰当前的成员方法或者成员变量。它可以在程序的任何位置出现(类的内部,类的外部)。可以被其他的类和对象去调用。子类呢可以继承和使用父类当中所有的,公共成员。

    class Person{
        public $name="李雷";
        public function fn(){
            // 1.可以在类的内部访问,对当前类的 内部可见
            echo $this->name;
        }
    }
    
    class Students extends Person{
        public function fn1(){
            // 2.可以在子类的内部访问,对子类的内部可见
            echo $this->name;   
            $this->fn();
        }
    }
    // 3.在类的外部可见
    $s1=new Person();
    $s1->fn();
    $s2=new Students();
    $s2->fn();
    $s2->fn1();
    

    2.9.2 private(私有成员)

    被private关键字所修饰的成员方法和变量,只能在所属类的内部被调用和修改,不可以在类外部访问,在子类中也不可以。

    <?php
    class Book{
        private $name='HTML';
        public function setName($name){
            // 1.在当前类内部 可访问
            $this->name=$name;
        }
        public function getName(){
            echo $this->name;
        }
        private function c1(){
            echo '123';
        }
    }
    
    class Histoty extends Book{
        public function getBookName(){
            // 2.在子类内部不可见 不可访问继承来的父类中的私有成员变量 私有方法
            echo $this->name;
            $this->c1();
        }
    }
    // $b1=new Book;
    // $b1->setName('PHP');
    // $b1->getName();
    // 3.在类的外部不可访问 私有成员变量或私有成员方法
    // $b1->name='js';
    // $b1->c1();
    
    $h1=new Histoty();
    $h1->getBookName();
    
    

    对于成员方法和成员变量,如果没有指定关键字,那就默认是public。

    2.9.3 protected(保护成员)

    被protected 修饰的类成员,可以在当前类和子类中被调用。去其他地方则不可以访问。

    class Person{
        protected $money=10;
        public function fn(){
            echo $this->money;
            // 1.在当前的内部可以访问
        }
    }
    class Stu extends Person{
        public function fn1(){
            echo $this->money;
            // 2. 可以在子类的内部访问
        }
    }
    // 3. 在类的外部不能直接访问,
    $p1=new Person;
    $p1->fn();
    // echo $p1->money;
    $s1=new Stu;
    $s1->fn1();
    

    2.10 静态成员(变量,方法)

    不是所有的方法都要通过创建对象来去调用的,我们可以。通过给变量或者方法加上static关键字来直接调用。也叫做访问静态成员。

    关键字::静态成员
    

    关键字可以有两种:

    • self,在类的内部调用静态成员是使用。
    • 静态成员所在的类名,在类的外部调用类内部的静态成员时所使用。
      在静态方法当中只能调用静态变量,而不能调用普通的变量。而普通方法里面可以调用静态变量。
      使用静态成员,除了可以不需要实例化对象外,另一个作用就是在对象被销毁后,仍然保留被修改的静态数据,以便于下次继续使用。
    class Book{
        static $num=0;//声明一个静态变量$num,初始值为0;
        public function showMe(){
            echo '您是第'.self::$num.'位访客';
            self::$num++;//
        }
    }
    $b1=new Book();
    $b1->showMe();
    $b2=new Book();
    $b2->showMe();
    echo '一共有'.Book::$num.'位访客';
    

    2.11 final 关键字

    被final修饰过的类和方法就是"最终的版本",如果类被final修饰过,该类不可以再被继承,也不能再有子类。

    final class Book{
        public $name='';
        public function __construct($name){
            $this->name=$name;
        }
    }
    class Histoty extends Book{
        public $height='';   
    }
    //结果: Fatal error: Class Histoty may not inherit from final class (Book)
    

    如果方法被final修饰过,方法在子类中不可以进行重写,也不可能被覆盖。

    
    class Book{
        public $name='';
        public function __construct($name){
            $this->name=$name;
        }
        final public function getName(){
            echo $this->name;
        }
    }
    class Histoty extends Book{
        public $height='';   
        public function  getName(){
            echo '123';
        }
    }
    //结果:Fatal error: Cannot override final method Book::getName() in
     
    

    2.12 对象类型检测

    instanceof操作符可以检测当前对象是属于哪一个类。

    ObjectName instanceof ClassName
    
    class Book{
        public $name='';
        public function __construct($name='佚名'){
            $this->name=$name;
        }
    }
    class History{
    
    }
    $a=new Book;
    $b=new History;
    // var_dump($a instanceof Book);//true
    var_dump($b instanceof Book);//false
    

    3.魔术方法(__)

    3.1 __get和__set() 方法

    这两个魔术方法的作用分别是:

    • 当程序试图去写入一个不存在或者不可见的成员变量的时候PHP就会执行__set()方法。__set()方法呢,包括有两个参数,分别是变量名称和变量的值,这两个参数不可省略。

    • 当程序调用一个未定义或者不可见的成员变量的时候,可以通过__get()方法来去读取变量的值.__get()这个方法有一个参数表示你要调用的这个变量名称。

    <?php
    class SportClass{
        public $height='1231';
        private $type='21312';
        public function __get($name){
            if(isset($this->$name)){//判断变量是否被声明
                echo '变量'.$name.'值:'.$this->$name.'<br>';
            }else{
                echo '变量'.$name.'未定义';
                $this->$name=0;
                echo $this->$name;
            }
        }
        public function __set($name,$value){
            if(isset($this->$name)){
                echo '私有成员';
                echo '变量'.$name.'赋值:'.$value.'<br>';
            }else{
                $this->$name=$value;
                echo '变量不存在';
            }
        }
    }
    $b=new SportClass();
    // echo $b->type;
    // echo $b->sex;
    // $b->type='213';
    $b->sex=234;
    echo $b->sex;
    

    3.2 __tostring()方法

    当使用echo或print输出对象时,将对象转化为字符串。

    class SportClass{
        private $type='21312';
        public function __tostring(){
            return $this->type;
        }
    }
    $b=new SportClass;
    echo $b;
    

    3.3 __autoload()方法

    尝试加载未定义的类是,触发__autoload()方法,__autoload()接受一个参数,参数是类的名称。

    function __autoload($classname){
        $class_path=lcfirst($classname).'Class.php';
        if(file_exists($class_path)){
            include_once($class_path);
        }
    }
    
    
    $b=new BaseFile;
    var_dump($b);
    $c=new Base();
    var_dump($c);
    

    3.4 中文字符串截取类

    在Php当中啊!我们经常要去对字符串进行一些截取。如果是英文字符串的话,我们可以直接使用substr()函数来去完成。但是当出现中文字符串的时候,如果你依然使用这个substr()函数,就有可能会出现乱码的情况。因为一个汉字是由两个字节组成的。所以当截取的字符如果出现奇数的时候,就有可能将一个汉字给拆分开来。从而导致输出一个不完整的汉字,显示出来就是乱码。

    相关文章

      网友评论

        本文标题:4面向对象

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