zoukankan      html  css  js  c++  java
  • php面向对象 封装继承多态 接口、重载、抽象类、最终类总结

    1、面向对象 封装继承多态  接口、重载、抽象类、最终类

    面向对象 封装继承多态 

    首先,在解释面向对象之前先解释下什么是面向对象?

    [面向对象]
    1、什么是类?
     具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念
    2、什么是对象?
    从类中拿到的具有具体属性值得个体,称为对象,对象是一个具体的个体

    所以,面向对象即我们专注对象来处理问题,通过从一个个具有属性和功能的类中拿到对象来处理问题。

    下面我们再来细说下面向对象的三大特征:继承/封装/多态

    一、继承

    在PHP中我们主要通关Extends关键字来实现继承   ->class Student extends Person{}

    下面是几个比较重要的注意事项:

    ①子类只能继承父类的非私有属性。
    ②子类继承父类后,相当于将父类的属性和方法copy到子类,可以直接使用$this调用该属性;
    ③PHP只能单继承,不支持一个类继承多个类。但是一个类可以进行多层继承(即A继承于B,而C又继承于A,C通过A间接继承了B)

    二、封装

    类实现封装是为了不让外面的类随意的修改一个类的成员变量,所以在定义一个类的成员的时候,我们使用private关键字设置这个成员的访问权限

    只能被这个类的其他成员方法调用,而不能被其他类中的方法调用,即通过本类中提供的方法来访问本类中的私有属性。

    ①所以在该类中我们会提供一个访问私有属性的方法

    ②然后我们一般会定义两个方法来实现对一个变量的操作,即:get()与set()方法。

    代码示例如下:

    复制代码
    class Person{
            private $name;
            private $age;
            
            public function __construct($name,$age){
                $this->name = $name;
                $this->age = $age;
            }
            function setAge($age){
                if($age>=0&&$age<=120){
                    $this->age = $age;
                }else{
                    error_log("年龄设置有误!");
                }
            }
            
            function getAge(){
                return $this->age;
            }
            public function say(){
                echo "我叫{$this->name},我今年{$this->age}岁了";
            }
            
            function __get($name){
                switch ($name) {
                    case 'name':
                        return $this ->$name."这是读取时加的文字";                    
                    case 'age':
                        return "0".$this ->$name;
                    default:
                        return $this ->$name;                    
                }
                
            }
            function __set($key,$value){
                
                if($key=="name"){
                    $this->$key = $value."这是设置时加的文字<br>";
                }else{
                    $this->$key = $value;
                }
            }
            function __isset($name){
                return isset($this->$name);
            }
            
            function __unset($name){
                if($name=="age"){
                    return;
                }
                 unset($this->$name);
            }
        }
     
    $zhangsan = new Person("zhangsan",14);
    $zhangsan->setAge(12);
    echo $zhangsan->getAge()."<br>";
    var_dump(isset($zhangsan->name));
    unset($zhangsan->age);
    echo $zhangsan->age;
    复制代码

    三、多态

    什么是多态?

    一个类,被多个子类继承,如果这个类的某个方法,在多个子类中,表现出不同的功能,我们称这种行为为多态。(同一个类的不同子类表现出不同的形态)

    那么我们如何来实现多态呢?

    子类继承父类 ->子类重写父类方法 ->父类引用指向子类对象

    abstract class Person{        注:父类使用abstract关键字修饰
    abstract function say();


    class Chinese extends Person{    注:子类重写父类方法
    function say(){
    echo "我是中国人<br>";
    }

    class English extends Person{    注:子类重写父类方法
    function say(){
    echo "我是英国人";
    }
    }

    $zhangsan = new Chinese();
    $zhangsan->say();
    $z = new English();
    $z->say();
    Person $p = new Chinese();   注:父类引用指向子类对象

    上述代码中,两个子类都是继承自同一父类,但因为都重写了父类的方法,表现出了不同的形态

     

    * 四、单例设计模式


    单例模式也叫单态模式
    可以保证一个类只能有一个对象实例
    实现要点:
    ①构造函数私有化,不允许使用new关键字创建对象。
    ②对外提供获取对象的方法,在方法中判断对象是否为空,如果为空则创建对象并返回,如果不为空则直接返回
    ③实例对象的属性以及获取对象的方法必须都是静态的。
    ④之后,创建对象只能使用我们提供的静态方法。

    示例代码如下:

     
    class Singleton{
    static public $Single = null;
    private function __construct(){}
    static function getSingle(){
    if(!self::$Single){
    self::$Single = new Singleton();//self代指类名 new Singleton()和newself()是完全一样的
    }
    
    return self::$Single;
    }
    
    function __destruct(){
    echo "我被销毁了<br>";
    }
    } 
    $s1 = Singleton::getSingle();
    $s1 = Singleton::getSingle();
    $s1 = Singleton::getSingle();

    抽象类、抽象方法、重载、接口

    抽象类

    定义:一个抽象的不能被实例化的类。

    定义形式(abstract关键字):

    abstract class 类名{

        // ...

    }

    抽象方法

    定义:一个只有方法头,没有方法体的方法

    定义形式(用abstract修饰方法)

    abstract class 类名{

        abstract function 方法名(形参列表); // 没有方法体,结尾分号不能省略

    }

    抽象类和抽象方法的细节:

    一个抽象方法必须在抽象类中,即方法为抽象的,那么其所在的类也不是是抽象的;

    抽象类中可以没有抽象方法;

    子类继承了父类,那么要么实现(“重写”)父类的抽象方法,要么在次定义为抽象的。

    重载

    含义:在“通常面向对象语言”中是指一个类可以名字相同但形参不同的方法的现象(如java)。

    如:

    class A{

        function f(){

        }

        function f($a){

        }

        function f($a,$b){

        }

    }

    php中的重载

    含义:是指当对一个对象或类使用其未定义的属性或方法的时候,其中的一些“处理机制”。

    属性重载:

    含义:对一个对象的不存在的属性进行使用的时候,这个类种预先设定好的应对方法(处理机制)

    属性,本质就是一个变量,其有4个操作:

    取值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__get();

    赋值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__set();

    判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__isset();

    判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__unset()。

    __set($属性名,值):

    含义:当对一个对象的不存在属性进行“赋值”的时候就会自动调用这个内部的魔术方法,它有两个形参,分别代表对不存在的属性进行赋值的时候的“属性名”和“属性值”。

     这个方法结合__get()方法,往往可以使我们定义的类,就有一种“可简便扩展属性”的特性,即类(或对象)的属性,可以更为方便自由,如下所示:

    class A{

        protected $prop_list = array();

        function __set($p,$v){

            $this->prop_list[$p] = $v;

        }

        function __get($p){

            return $this->prop_list[$p];

        }

    }

    __isset()

    含义:当对一个对象的不存在属性进行“判断”的时候就会自动调用这个内部的魔术方法。

    __unset()

    含义:当对一个对象的不存在属性进行“销毁”的时候就会自动调用这个内部的魔术方法。

    方法重载

    当对一个对象的不存在的实例方法进行“调用”的时候会自动调用类中的__call()这个魔术方法;

    当对一个对象的不存在的静态方法进行“调用”的时候会自动调用类中的__callstatic()这个魔术方法。

    php中实现通常的面向对象语言的“方法重载”(利用__call()和__callstatic()方法),如:

    <?php

    class A{

        function __call($methodName,$arguments){

            switch ($methodName) {

                case 'f1': // 调用了f1这个不存在的方法

                    # 调用了方法名为f1的这一系列重载方法

                    if(count($arguments) == 0){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 1){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 2){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 3){

                        // 这里拿这些参数做这个方法的事情...

                    }

                    // ...

                    break;

                case 'f2': // 调用了f2这个不存在的方法

                    # 调用了方法名为f2的这一系列重载方法

                    if(count($arguments) == 0){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 1){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 2){

                        // 这里拿这些参数做这个方法的事情...

                    }else if(count($arguments) == 3){

                        // 这里拿这些参数做这个方法的事情...

                    }

                    // ...

                    break;

                default:

                    break;

            }

        }

    }

    ?>

    接口

    定义形式

    interface 接口名{

        常量1;

        常量2;

        ...

        抽象方法1;

        抽象方法2;

        ...

    }

    说明:

    接口中只有常量(接口常量)和抽象方法两种成员;

    接口常量的使用形式为:接口名称::常量名称;

    接口中的抽象方法,不要使用abstract修饰,也需要使用访问控制修饰符,因为其天然就是Public;

    php中接口和类一样也可以继承(接口继承接口)。

    还谈php和java面向对象

    相同点:

    抽象类和抽象方法,及它们之间的细节都一样;

    php的接口和java的接口都一样。

    不同点:

    重载不一样,php重载和其他面向对象语言的重载不同,而java和其他面向对对象语言的重载一样。

    最终类final class:

    在定义一个类的时候,在class关键字前面使用final关键,则表示该类“不可继承”(禁止继承);

    如下:

    final class 类名{

    //类成员定义。。。。

    }

    最终方法

    就是在方法定义的前面,使用关键字final,表示该方法“不可覆盖”——禁止覆盖。

     

    抽象类
    定义:一个抽象的不能被实例化的类。定义形式(abstract关键字):
    abstract class 类名{    // ...}123抽象方法
    定义:一个只有方法头,没有方法体的方法
    定义形式(用abstract修饰方法)
    abstract class 类名{    abstract function 方法名(形参列表); // 没有方法体,结尾分号不能省略}123抽象类和抽象方法的细节:
    一个抽象方法必须在抽象类中,即方法为抽象的,那么其所在的类也不是是抽象的;抽象类中可以没有抽象方法;子类继承了父类,那么要么实现(“重写”)父类的抽象方法,要么在次定义为抽象的。重载
    含义:在“通常面向对象语言”中是指一个类可以名字相同但形参不同的方法的现象(如java)。
    如:
    class A{    function f(){
        }    function f($a){
        }    function f($a,$b){
        }}1234567891011php中的重载
    含义:是指当对一个对象或类使用其未定义的属性或方法的时候,其中的一些“处理机制”。
    属性重载:
    含义:对一个对象的不存在的属性进行使用的时候,这个类种预先设定好的应对方法(处理机制)属性,本质就是一个变量,其有4个操作:
    取值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__get();赋值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__set();判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__isset();判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__unset()。__set($属性名,值):
    含义:当对一个对象的不存在属性进行“赋值”的时候就会自动调用这个内部的魔术方法,它有两个形参,分别代表对不存在的属性进行赋值的时候的“属性名”和“属性值”。
     这个方法结合__get()方法,往往可以使我们定义的类,就有一种“可简便扩展属性”的特性,即类(或对象)的属性,可以更为方便自由,如下所示:
    class A{    protected $prop_list = array();    function __set($p,$v){        $this->prop_list[$p] = $v;    }    function __get($p){        return $this->prop_list[$p];    }}123456789__isset()
    含义:当对一个对象的不存在属性进行“判断”的时候就会自动调用这个内部的魔术方法。__unset()
    含义:当对一个对象的不存在属性进行“销毁”的时候就会自动调用这个内部的魔术方法。方法重载
    当对一个对象的不存在的实例方法进行“调用”的时候会自动调用类中的__call()这个魔术方法;
    当对一个对象的不存在的静态方法进行“调用”的时候会自动调用类中的__callstatic()这个魔术方法。
    php中实现通常的面向对象语言的“方法重载”(利用__call()和__callstatic()方法),如:
    <?phpclass A{
        function __call($methodName,$arguments){        switch ($methodName) {            case 'f1': // 调用了f1这个不存在的方法                # 调用了方法名为f1的这一系列重载方法                if(count($arguments) == 0){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 1){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 2){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 3){                    // 这里拿这些参数做这个方法的事情...                }                // ...                break;            case 'f2': // 调用了f2这个不存在的方法                # 调用了方法名为f2的这一系列重载方法                if(count($arguments) == 0){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 1){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 2){                    // 这里拿这些参数做这个方法的事情...                }else if(count($arguments) == 3){                    // 这里拿这些参数做这个方法的事情...                }                // ...                break;            default:                break;        }    }}?>12345678910111213141516171819202122232425262728293031323334353637接口
    定义形式
    interface 接口名{    常量1;    常量2;    ...    抽象方法1;    抽象方法2;    ...}12345678说明:
    接口中只有常量(接口常量)和抽象方法两种成员;接口常量的使用形式为:接口名称::常量名称;接口中的抽象方法,不要使用abstract修饰,也需要使用访问控制修饰符,因为其天然就是Public;php中接口和类一样也可以继承(接口继承接口)。还谈php和java面向对象
    相同点:
    抽象类和抽象方法,及它们之间的细节都一样;php的接口和java的接口都一样。不同点:
    重载不一样,php重载和其他面向对象语言的重载不同,而java和其他面向对对象语言的重载一样。--------------------- 作者:宿罪 来源:CSDN 原文:https://blog.csdn.net/ydxlt/article/details/50667454 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    如何通过网页远程控制linux --远程访问Linux桌面
    用Python快速实现HTTP和FTP服务器
    两台server间测速工具iperf3
    向Linux进程发送信号
    谓语必须为动词或动词短语~
    2021-6-2 支撑
    运用学过的设计原则和思想完善之前讲的性能计数器项目(下)
    运用学过的设计原则和思想完善之前讲的性能计数器项目(上)
    总结回顾面向对象、设计原则、编程规范、重构技巧等知识点
    实战二(下):重构ID生成器项目中各函数的异常处理代码
  • 原文地址:https://www.cnblogs.com/qxandxt/p/10469272.html
Copyright © 2011-2022 走看看