zoukankan      html  css  js  c++  java
  • php分享二十二:php面向对象

    1:static访问符

    • 在类中使用static有两种主要用途、定义静态成员和定义静态方法。静态成员只保留一个变量的值,这个值对所有实例都是有效的
    • 类的方法是static的,他所访问的属性也必须是static的

    2:static后期静态绑定

    什么是静态绑定?

    abstract class U {
    
    }
    class u1 extends U {
        public static function create() {
            return new u1();
        }
    
    }
    class u2 extends U {
        public static function create(){
            return new u2();
        }
    }
    

    这段代码正常工作是没问题,但大量重复的代码会很烦人

    我不想在每个子类中添加create方法,如果把create方法放在超类U中,代码可能是

    abstract class U
    {
        public static function create()
        {
           //return new self();  //self 会报错,self对该类所起的作用与$this对对象所起的作用并不完全相同。self指的不是调用上下文,他指的是解析上下文,
    //因此如果运行上面的列子,将会得到
    //Fatal error: Cannot instantiate abstract class U in D:wampwwwtestoopstatic.php on line 21
    //因此self被解析为定义create的U,而不是解析为调用self的u1类。

        //static不仅可以用于实例化,和self,parent一样还可以作为静态方法的调用标识符,甚至是从非静态上下文中调用
        return new static(); } } class u1 extends U{ } class u2 extends U{ } $res = u1::create(); var_dump($res);

     static不仅可以用于实例化,和self,parent一样还可以作为静态方法的调用标识符,甚至是从非静态上下文中调用

    abstract class U
    {
        private $group;
        public function __construct()
        {
            $this->group = static::getGroup();
        }
    
        public static function create()
        {
            return new static();
        }
    
        static function getGroup()
        {
            return 'default';
        }
    
    }
    
    class u1 extends U
    {
        
    }
    
    class u2 extends U
    {
        static function getGroup()
        {
            return 'u2';
        }
    
    }
    
    class u3 extends u2
    {
        
    }
    
    print_r(u1::create());
    

    u1 Object ( [group:U:private] => default )

    u3 Object ( [group:U:private] => u2 )

    例子:

    class A {
        public static function foo() {
            static::who();
        }
     
        public static function who() {
            echo __CLASS__."
    ";
        }
    }
    class B extends A {
        public static function test() {
            A::foo();  //如果换成static,则向后绑定,如果是A,则最底层的类是A
            parent::foo();
            self::foo();
        }
     
        public static function who() {
            echo __CLASS__."
    ";
        }
    }
    class C extends B {
        public static function who() {
            echo __CLASS__."
    ";
        }
    }
    C::test();
    

     输出:A C C

    3: 属性不能被定义为 final,只有类和方法才能被定义为 final。

    如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

    4:对象复制

    5:对象继承

    parent能调用父类的非静态方法吗?

    self能调用父类的静态方法吗?

    php支持继承多个类吗?

    父类调用之类怎么调用?

    子类调用父类怎么调用?

    $this能调用静态方法吗?

    同样的类名和接口名可以放在一起吗?

    子类的同名访问符可以小于父类的吗?

    php支持多态吗?

    1> parent能调用父类的非静态方法吗?

    parent既能调用父类的静态方法,也可以调用父类的非静态方法; parent不可以调用子类,只能调用父类的; parent关键字解决的就是调用父类的方法;

      self无论父类还是子类的静态方法,非静态方法都可以调用(对所有的无限制)

      parent常用于构造函数中调用父类的构造函数

    2>self能调用父类的静态方法吗?

    3>父类调用之类怎么调用?

    静态方法,属性用static,$this(虽然可以访问,但是不建议这样来做)

    非静态方法,属性用$this, static

    4>子类调用父类怎么调用?

    用$this, parent, static

    5>如果子类和父类有相同的方法,但是父类的是private方法,父类调用的时候调用的是哪个方法?

    父类调用的是他自己的,而不是子类的。对于私有方法(private)修饰的方法,$this找的方法是先找本类里的。 protect,public都可以被覆盖。

    class Child
    {
        public function __construct()
        {
            $this->setInstance($this);
        }
    
        private function setInstance($instance)
        {
            echo 'Child';
        }
    }
    
    class ChildChild extends Child
    {
    
        public function __construct()
        {
            parent::__construct();
        }
    
        public  function setInstance($instance)
        {
            echo 'ChildChild';
        }
    }
    $obj = new ChildChild();
    

     输出:Child 【因为他是private,$this调用的时候调用它】

    如果改成public,或protected,则返回ChildChild

    5>子类的同名访问符可以小于父类的吗?

    子类的修饰符号不能小于父类的

    3>同样的类名和接口名不能放在一起。

    同样的类名和接口名可以放在一起吗?

    Class and Interface share SAME namespace!

    class k{}
    interface k {}    // Fatal error: Cannot redeclare class k

    6:$this, self,parent,static

    1> $this访问变量不加$, self:: 访问需要加

    $this->name;   self::$sName;

    2>

    $this能访问静态变量,静态方法,但是不能访问常量;

    而self, parent, static 不能访问非静态变量,只能访问静态的变量或常量; 但是self,parent,static都能访问非静态方法。self也能访问父类的非静态方法和静态方法。

    php支持多态吗?

    多态:多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。

    PHP只支持覆盖(override),而不支持重载(overload)。

    PHP5 中重载可以通过 __get, __set, and __call 几个特殊方法来进行。当 Zend 引擎试图访问一个成员并没有找到时,PHP将会调用这些方法。

    public function __call($method, $p)
    {
        print("Invoking $method()<br>
    ");
        if($method == 'display')
        {
            if(is_object($p[0]))
                $this->displayObject($p[0]);
            else
                if(is_array($p[0]))
                    $this->displayArray($p[0]);
                else
                    $this->displayScalar($p[0]);
        }
    }
    

     __CLASS__, __FUNCTION__ 在哪个类里,就显示哪个,而不管$this是谁

    class Child
    {
        public function __construct()
        {
            static::setInstance($this);
        }
    }
    
    class ChildChild extends Child
    {
    
        public function __construct()
        {
            parent::__construct();
        }
    
        public  function setInstance($instance)
        {
            echo __CLASS__ . ' || ' . __FUNCTION__;
            echo 'childChild';
        }
    }
    $obj = new ChildChild();
    

     返回: ChildChild || setInstance childChild

    static访问符号的顺序为: 从后往前

    子类 > 本类 > 父类

    class Base
    {
        protected static $instances;
    
        public function setInstance($instance)
        {
            echo 'Base';
        }
    }
    class Child extends Base
    {
        public function __construct()
        {
            static::setInstance($this);
        }
    
        public function setInstance($instance)
        {
            echo 'Child';
        }
    }
    
    class ChildChild extends Child
    {
        public function setInstance($instance)
        {
            echo 'ChildChild';
        }
    }
    $obj = new ChildChild();
    

     输出: ChildChild

    总结:

    访问静态方法,静态属性:static,parent,self, $this

    访问常量: self, parent, static

    访问非静态方法,属性: $this, static, parent, self

    子类访问父类: $this, parent, self, static

    父类访问子类: static, $this

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/Alight/p/5209284.html
Copyright © 2011-2022 走看看