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

  • 相关阅读:
    StreamBox Ripper 将rm转mp3时候出现g2支持的问题
    网上英语学习资源大整理
    516 find
    怎样使孩子愿意学习
    Oracle日期函数
    Create PR/PO 以后Status的变化
    销售到出仓所经历的表
    UTL_FILE 的用法
    Oracle EBS常用数据表
    我的blog今日开园
  • 原文地址:https://www.cnblogs.com/Alight/p/5209284.html
Copyright © 2011-2022 走看看