zoukankan      html  css  js  c++  java
  • 2018-3-6 对象的继承

    对象继承:

    A具有某些特征,类B也具有A类的所有特征,同时具有自己更多的一些特征,此时发现,B类使用A的特征信息并继续添加自己的一些特有特征信息。我们可以说B类继承于A类。

    class jizuidongwu{
        public $prop1 = "有脊椎";
        function show1(){
            echo "<br />特征:" . $this->prop1;
        }
    
    }
    class human extends jizuidongwu{  //human继承于jizuidongwu
        public $prop2 = "两脚走路";
        function show2(){
            echo "<br />特征:" . $this->prop2;
        }
    }
    $person1 = new human();
    $person1->show1();  //$person1是human的对象,但可以执行jizuidongwu的方法
    $person1->show2();

    概念:

    继承:一个类从另一个已有的类获得属性,称为继承。

    派生:从一个已有的类产生一个新的类,称为派生。

    父类/子类:已有类为父类,新建类为子类。父类也叫“基类”,子类也叫“派生类”

    单继承:一个类只能从一个上级类继承其特性信息。PHP和大多数面向对象的语言都是单继承模式。C++是多继承。

    访问(权限)修饰符:

    在类中的成员,通常都可以在前面加上以下3个修饰符:

    public:公共的,共有的,公开的

    protected:受保护的

    private:私有的

    访问位置:

    1、private某个类的内部;

    class C{
        private $p1 = 1;
        public function showInfo(){
            echo "<br />属性p1=" . $this->p1;
        }
    }
    class D extends C{
        private $p2 = 2;
        public function showInfo2(){
            echo "<br />属性p1=" . $this->p1;//访问的是上级的似有成员$p1
            echo "<br />属性p2=" . $this->p2;//访问的是自己的私有成员$p1
        }
    }
    $d1 = new D();
    $d1->showInfo2();
    echo "<br />在类外p2=" . $d1->p2;//这一行出错,因为在“外面”不能访问私有成员$p2

    2、protected某个类及其子类的内部;

    class C{
        protected $p1 = 1;
        public function showInfo(){
            echo "<br />属性p1=" . $this->p1;
        }
    }
    class D extends C{
        protected $p2 = 2;
        public function showInfo2(){
            echo "<br />属性p1=" . $this->p1;//访问的是上级的受保护成员$p1
            echo "<br />属性p2=" . $this->p2;//访问的是自己的受保护成员$p1
        }
    }
    $d1 = new D();
    $d1->showInfo2();
    echo "<br />在类外p2=" . $d1->p2;//这一行出错,因为在“外面”不能访问受保护成员$p2

    3、public所有位置,内部和外部都可以使用;

    class C{
        public $p1 = 1;
        public function showInfo(){
            echo "<br />属性p1=" . $this->p1;
            echo "<br />属性p2=" . $this->p2;//此时可以访问下级的$p2(但很不常用)
        }
    }
    class D extends C{        //D继承于C
        public $p2 = 2;
        public function showInfo2(){
            echo "<br />属性p1=" . $this->p1;//访问的是上级的$p1(常见情形)
            echo "<br />属性p2=" . $this->p2;
        }
    }
    $d1 = new D();
    $d1->showInfo2();
    echo "<br />在类外p2=" . $d1->p2;  //说明在类外也可以调用public $p2 = 2;
    $d1->showInfo();

    此时输出结果为:

    属性p1=1
    属性p2=2
    在类外p2=2
    属性p1=1
    属性p2=2

    总结以上,访问修饰限定符的使用范围:

    范围

    本类内

    继承关系类内

    类外

    public

    可以

    可以

    可以

    protected

    可以

    可以

    不可以

    private

    可以

    不可以

    不可以

    parent代表父类:

    self代表“本类”;

    parent通常用于在子类中调用父类的成员的时候使用,多数通常就是使用父类的“静态类”成员。

    class C{
        public $p1 = 1;
        function showMe(){
            echo "<br />我是父类,数据有:";
            echo "<br />C中p1=" . $this->p1;
        }
        function __construct($p1){
            $this->p1 = $p1;
        }
    }
    class D extends C{
        public $p2 = 2;
        function __construct($p1,$p2){
            //经典用法
            parent::__construct($p1);//调用父类的构造函数来初始化p1
            $this->p2 = $p2;    //初始化p2
        }
        function showMe2(){
            echo "<br />我是子类,数据有:";
            //基本用法:
            parent::showMe();    //调用父类的showMe方法,
            echo "<br />D中p2=" . $this->p2;
        }
    }
    $d1 = new D(10,20);    //此时就需要尊照构造函数的参数结构来使用
    $d1->showMe2();    

    构造方法和析构方法在继承中的表现:

    子类中没有定义构造方法时,会自动调用父类的构造方法。因此实例化子类时,需按照父类的构造方法的形式进行。

    class C{
        public $p1 = 1;
        public $p3 = 3;
        function __construct($p1,$p3){   //设置父类的构造方法
            echo "<br />父类构造方法调用了";
            $this->p1 = $p1;
            $this->p3 = $p3;
        }
    }
    class D extends C{
        public $p2 = 2;
        function __construct($p1,$p2, $p3){  //设置子类的构造方法
            echo "<br />子类构造方法调用了";
            parent::__construct($p1,$p3);  //调用父类构造方法
            $this->p2 = $p2;
        }
        function showInfo(){  //方法名
            echo "<br />p1=$this->p1";
            echo "<br />p2=$this->p2";
            echo "<br />p3=$this->p3";
        }
    }
    $d1 = new D(10, 20, 30);  //新建对象$d1
    $d1->showInfo();  //调用方法

    很多时候,在构造方法中,子类都可以通过调用父类的构造方法节省代码,增加可读性。

    当子类定义了自己的析构方法后,则就不会自动调用父类的析构方法的,但可以手动调用:parent::__destruct()

    重写:

    重写又叫覆盖,将从父类继承下来的属性或方法重新“定义”。重写发生在父类底下的子类中。

    class Jizhuidongwu{
        public $p1 = "具有脊椎";
        function showMe(){  //父类方法
            echo "<br />我是脊椎动物,特征为:";
            echo "<br />属性p1=" . $this->p1;
        }
    }
    class Human extends Jizhuidongwu{
        public $p1 = "具有28节脊椎骨的脊椎";//28是假设
        public $p2 = '有32颗牙齿';
        function showMe(){  //重写方法
            echo "<br />我是人类,特征为:";
            //echo "<br />属性p1:" . $this->p1;
            //实际应用中,通常上一行(显示父类信息)会使用下一行代替
            parent::showMe();    //这样可以更节省
            echo "<br />属性p2:" . $this->p2;
        }
    }
    $h1 = new Human();
    $h1->showMe();

    重写具有一定的要求,主要就是访问权限以及参数。

    访问权限方面,下级的访问权限应不低于上级的访问权限。

    上级:public  下级:只能public

    上级:protected  下级: protected, public

    上级:private   下级:private  protected  public——实际此情况无意义。

    方法的参数形式应该与父类的保持一致。

    构造方法在重写的时候参数可以不一致。

    最终类final class:

    最终类不会再继续往下拓展,即这就是最底下的类,可以定义对象,不能有子类。

    形式:final class 类名{     类定义     }

    最终方法 final  method:这个方法不会被下级类覆盖。

    final  function  方法名(){    方法定义     }

    设计模式:解决问题的常用做法,比较好的经验总结。针对不同问题,有不同的解决办法,这就是不同的设计模式。

    工厂模式:有时候,我们需要实例化许多类,用来得到对象。

    设计一个“工厂”(类)作用是“生产”各种对象。通常这种工厂,只需要制定类名,就可以获取一个该类的对象。

    class factory{
        //Instance表示“实例”,“对象”
        static function getInstance($className){
            if(file_exists('./class/' . $className . ".class.php")){
                $obj1 = new $className();
                return $obj1;
            }
            else{
                return null;//也可以die();
            }
        }
    }
    $obj1 = factory::getInstance("A");//获取类A的一个对象
    $obj2 = factory::getInstance("B");//获取类B的一个对象
    $obj3 = factory::getInstance("A");//再获取类A的一个对象
  • 相关阅读:
    XML相关知识点
    MLPlatform开发日志
    1.0 es6 箭头函数
    基本数学概念
    4.4 thymeleaf使用补充
    vim操作手册
    eclise创建后台项目
    正则表达式
    数据库隔离级别
    1. gradle的使用教程
  • 原文地址:https://www.cnblogs.com/dns6/p/8512610.html
Copyright © 2011-2022 走看看