PHP-静态方法继承等分析

<?php
    class A {
        const CONST_NAME = ‘A‘;
        public static $static_name = ‘A‘;
        public static $static_name_no_rewrite = ‘A‘;

        private static $_instance;

        public static function static_func() {
            echo ‘A‘;
        }

        public static function static_func_no_rewrite() {
            echo ‘A‘;
        }

        public static function static_extends_self() {
            echo self::$static_name;
        }

        public static function static_extends_no_rewrite_self() {
            echo self::$static_name;
        }

        public static function static_extends_no_vars() {
            return self::$static_no_vars;
        }

        public static function get_instance() {
            if (empty(self::$_instance)) {
                self::$_instance = new self();
            }
            return self::$_instance;
        }
    }

    class B extends A {
        const CONST_NAME = ‘B‘;
        public static $static_name = ‘B‘;
        public static $static_no_vars = ‘B‘;

        //重写
        public static function static_func() {
            echo ‘B‘;
        }

        public static function static_extends_self() {
            echo self::$static_name;
        }
    }
    //是否继承后是有了一个父类的引用

    //1.查看父类和子类的初始情况
    $str = ‘1.查看父类和子类的初始情况‘;
    echo ‘<hr />‘;
    echo $str, ‘<br />‘;
    echo ‘A::CONST_NAME->‘, A::CONST_NAME, ‘<br />‘;
    echo ‘B::CONST_NAME->‘, B::CONST_NAME, ‘<br />‘;
    echo ‘A::$static_name->‘, A::$static_name, ‘<br />‘;
    echo ‘B::$static_name->‘, B::$static_name, ‘<br />‘;
    echo ‘B::$static_name_no_rewrite->‘, B::$static_name_no_rewrite, ‘<br />‘;
    echo ‘B::$static_name_no_rewrite->‘, B::$static_name_no_rewrite, ‘<br />‘;
    echo ‘结论:静态属性或类常量可以被继承<br />‘;
    echo ‘<hr />‘;

    //2.测试重定义的类属性 修改子类(父类)的值父类(子类)的值是否会改变
    $str = ‘2.测试重定义的类属性 修改子类(父类)的值父类(子类)的值是否会改变‘;
    echo $str, ‘<br />‘;
    A::$static_name = ‘M_A‘;
    echo "修改->A::\$static_name = ‘M_A‘<br />";
    echo ‘A::$static_name->‘, A::$static_name, ‘<br />‘;
    echo ‘B::$static_name->‘, B::$static_name, ‘<br />‘;
    B::$static_name = ‘M_B‘;
    echo "修改->B::\$static_name = ‘M_B‘<br />";
    echo ‘A::$static_name->‘, A::$static_name, ‘<br />‘;
    echo ‘B::$static_name->‘, B::$static_name, ‘<br />‘;
    echo ‘结论:继承关系的两个类,如果子类重定义了父类的静态属性,则修改父类(子类)的静态属性或常量不会影响到子类(父类)的对应静态属性<br />‘;
    echo ‘<hr />‘;

    //3.测试没有重定义的类属性 修改子类(父类)的值父类(子类)的值是否会改变
    $str = ‘3.测试没有重定义的类属性 修改子类(父类)的值父类(子类)的值是否会改变‘;
    echo $str, ‘<br />‘;
    echo ‘A::$static_name_no_rewrite->‘, A::$static_name_no_rewrite, ‘<br />‘;
    echo ‘B::$static_name_no_rewrite->‘, B::$static_name_no_rewrite, ‘<br />‘;
    A::$static_name_no_rewrite = ‘M_A‘;
    echo "修改->A::\$static_name_no_rewrite = ‘M_A‘<br />";
    echo ‘A::$static_name_no_rewrite->‘, A::$static_name_no_rewrite, ‘<br />‘;
    echo ‘B::$static_name_no_rewrite->‘, B::$static_name_no_rewrite, ‘<br />‘;
    B::$static_name_no_rewrite = ‘M_B‘;
    echo "修改->B::\$static_name_no_rewrite = ‘M_B‘<br />";
    echo ‘A::$static_name_no_rewrite->‘, A::$static_name_no_rewrite, ‘<br />‘;
    echo ‘B::$static_name_no_rewrite->‘, B::$static_name_no_rewrite, ‘<br />‘;
    echo ‘结论:如果子类没有重定义父类的某个静态属性,则修改父类(子类)则子类(父类)的对应静态属性也随之改变<br />‘;
    echo ‘更深结论:子类继承父类会有一个父类的引用指向父类那块内存,如果子类没有重定义一个属性(放到本类内存下)就会调用父类的属性<br />‘;
    echo ‘<hr />‘;

    //4.静态方法是否能继承
    $str = ‘4.静态方法是否能继承‘;
    echo $str, ‘<br />‘;
    echo ‘A::static_func_no_rewrite()->‘, A::static_func_no_rewrite(), ‘<br />‘;
    echo ‘B::static_func_no_rewrite()->‘, B::static_func_no_rewrite(), ‘<br />‘;
    echo ‘结论:静态方法可以继承!‘;
    echo ‘<hr />‘;

    //5.静态方法是否能被重写
    $str = ‘5.静态方法是否能被重写‘;
    echo $str, ‘<br />‘;
    echo ‘A::static_func()->‘, A::static_func(), ‘<br />‘;
    echo ‘B::static_func()->‘, B::static_func(), ‘<br />‘;
    echo ‘结论:静态方法可以被重写!‘;
    echo ‘<hr />‘;

    //6.父类静态方法中有self, 子类继承此方法没有重写后调用的self是谁?
    $str = ‘6.父类静态方法中有self, 子类继承此方法没有重写后调用的self是谁?‘;
    echo $str, ‘<br />‘;
    echo ‘A::static_extends_no_rewrite_self()->‘, A::static_extends_no_rewrite_self(), ‘<br />‘;
    echo ‘B::static_extends_no_rewrite_self()->‘, B::static_extends_no_rewrite_self(), ‘<br />‘;
    echo ‘结论:与3相同, 如若没有重写, 则只是子类对父类的一个引用, 如果子类中没有, 就去父类中寻找, 而且找到的也是依赖于父类!‘;
    echo ‘更深结论:在PHP单例的继承中, 父类::get_instance()方法中返回new self(), 如果子类没有重写, 则返回父类的实例!‘;
    echo ‘<hr />‘;

    //7.父类静态方法中有self, 子类继承此方法重写后调用的self是谁?
    $str = ‘7.父类静态方法中有self, 子类继承此方法重写后调用的self是谁?‘;
    echo $str, ‘<br />‘;
    echo ‘A::static_extends_self()->‘, A::static_extends_self(), ‘<br />‘;
    echo ‘B::static_extends_self()->‘, B::static_extends_self(), ‘<br />‘;
    echo ‘结论:子类覆盖父类的方法后, 如果其中有self属性, 则此时会覆盖父类的self, 即此时的self为对象本身‘;
    echo ‘<hr />‘;

    //8.父类静态方法调用本身没有子类却有的静态属性(来验证上述6推测, 如果是引用, 则会为空)
    $str = ‘8.子类调用父类静态方法调用父类没有子类却有的self的静态属性(来验证上述6推测, 如果是引用, 则会为空)‘;
    echo $str, ‘<br />‘;
    //echo ‘B::static_extends_no_vars()->‘, B::static_extends_no_vars(), ‘<br />‘;
    echo ‘B::static_extends_no_vars()->报错<br />‘;
    echo ‘结论:程序报错, 显示A没有此属性, 说明是子类对父类的一个引用!子类如果没有重写父类的属性或静态方法, 则调用父类的!包括self!‘;
    echo ‘<hr />‘;

    //9.测试下6中的推断, 即单例模式中self
    $str = ‘9.测试下6中的推断, 即单例模式中self‘;
    echo $str, ‘<br />‘;
    echo ‘get_class(B::get_instance())->‘, get_class(B::get_instance()), ‘<br />‘;
    echo ‘结论:说明6中的更深推断是正确的!‘;
    echo ‘<hr />‘;

    //10.测试实例调用静态属性或常量
    $str = ‘测试实例调用静态属性或常量‘;
    echo $str, ‘<br />‘;
    $a = new A();
    //echo ‘$a = new A();echo $a->CONST_NAME->‘, $a->CONST_NAME, ‘<br />‘;
    echo ‘$a = new A();echo $a->CONST_NAME->报错<br />‘;
    //echo ‘echo $a->$static_name->‘, $a->$static_name, ‘<br />‘;
    echo ‘echo $a->$static_name->报错<br />‘;
    echo ‘结论:实例不能调用类的静态属性或常量!调用静态属性会转变为变量的变量, 调用常量会调用实例的对应属性!‘;
    echo ‘<hr />‘;

    //11.测试实例调用静态方法
    $str = ‘测试实例调用静态属性或常量‘;
    echo $str, ‘<br />‘;
    echo ‘$a->static_func()->‘, $a->static_func(), ‘<br />‘;
    echo ‘$a->static_extends_self()->‘, $a->static_extends_self(), ‘<br />‘;
    echo ‘结论:实例可以调用静态方法, 甚至静态方法中包含self!‘;
    echo ‘<hr />‘;

PHP-静态方法继承等分析,布布扣,bubuko.com

时间: 2024-10-25 04:09:32

PHP-静态方法继承等分析的相关文章

谈谈java中静态变量与静态方法继承的问题

谈谈java中静态变量与静态方法继承的问题 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量的继承和静态方法继承问题的测试. 首先我先建一个父类: 这样我在建一个子类: 这些都准备好以后,我对子类创建对象,然后用  类名.静态变量/静态方法  和  对象名.静态方法/静态变量  对他们输出的结果进行测试. 这样输出种类有: 这样我输出的结果是: 这样来总结一下: 1. 通过类名来调用子类中的静态变量和静态方法,当父类与子类相同时是,子类会隐藏父类

Java 语言静态变量和静态方法继承问题(转)

首先,定义一个类A如下 class A { static int a = 1; static int b = 2; public static void printA() { System.out.println(a); } public static void printB() { System.out.println(b); } } class A {     static int a = 1;     static int b = 2;     public static void pri

第51课 继承对象模型分析——多态的本质分析

多态的本质分析 用C写面向对象,用C实现多态 #ifndef _51_2_H_ #define _51_2_H_ typedef void Demo; typedef void Derived; Demo* Demo_Create(int i, int j); int Demo_GetI(Demo* pThis); int Demo_GetJ(Demo* pThis); int Demo_Add(Demo* pThis, int value); void Demo_Free(Demo* pThi

js中5中继承方式分析

//1.借用式继承   把sup的构造函数里的属性方法克隆一份sub实例对象 function Super(){ this.val = 1; this.fun1 = function(){console.log('fun1')}; } Super.prototype.name = "name"; Super.prototype.fun2 = function(){console.log('fun2')}; function Sub(){ Super.call(this); } var

Swift 中的静态方法继承

Base and Derived Classes: class BaseClass{ class func staticMethod(){ println("BaseClass.staticMethod") } class func staticMethodWithSelfCall(){ self.staticMethod() } func instanceMethodWithStaticCall(){ self.dynamicType.staticMethod() } } class

TypeScript静态方法继承

同步版本 class Foo { static boo<T extends typeof Foo>(this: T, a: number): InstanceType<T> { return (new this()) as InstanceType<T>; } } class Bar extends Foo {} // b: Bar let b = Bar.boo(1); 异步版本 class Foo { static async boo<T extends ty

Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源代码分析

上一章我们分析了Scene与Layer相关类的源代码,对Cocos2d-x的场景有了初步了解,这章我们来分析一下场景变换TransitionScene源代码. 直接看TransitionScene的定义 class CC_DLL TransitionScene : public Scene { public: /** Orientation Type used by some transitions */ enum class Orientation { /// An horizontal or

如何继承Date对象?由一道题彻底弄懂JS继承。

前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------长文+多图预警,需要花费一定时间---------- 故事是从一次实际需求中开始的... 某天,某人向我寻求了一次帮助,要协助写一个日期工具类,要求: 此类继承自Date,拥有Date的所有属性和对象 此类可以自由拓展方法 形象点描述,就是要求可以这样: // 假设最终的类是 MyDate,有一个getTest拓展方法 let date = new MyDate(); // 调用Date的方法,输出GM

看到的关于虚函数继承及虚继承解释比较好的文章的复制

(来源于:http://blog.chinaunix.net/uid-25132162-id-1564955.html) 1.空类,空类单继承,空类多继承的sizeof #include <iostream> using namespace std; class Base1 { }; class Base2 { }; class Derived1:public Base1 { }; class Derived2:public Base1, public Base2 { }; int main(