网上关于静态属性和方法的继承问题,答案千奇百怪,干脆直接代码试了下:
<code>class Base { public static $var = 'var'; public static function testStaticFun() { echo 'func'; } } class A extends Base { public function testSelf() { echo self::$var; } public function testParent() { echo parent::$var; } public function setSelf() { self::$var = 'self'; } public function setParent() { parent::$var = 'parent'; } public static function testStaticFun() { parent::testStaticFun(); echo 'over'; } } $objA = new A(); $objA->testSelf(); // var $objA->testParent(); // var $objA->setSelf(); $objA->testSelf(); // self $objA->testParent(); // self echo Base::$var; // self $objA->setParent(); $objA->testSelf(); // parent $objA->testParent(); // parent echo Base::$var; // parent Base::testStaticFun(); // func A::testStaticFun(); // func over </code>
所以 php 中静态的继承究竟是什么情况?是不是和其他语言比如 java 在静态继承的行为上有区别?父类的静态属性和方法会不会被覆盖?继承之后静态属性是不是只有一份?继承实现的原理是什么?
网上关于静态属性和方法的继承问题,答案千奇百怪,干脆直接代码试了下:
<code>class Base { public static $var = 'var'; public static function testStaticFun() { echo 'func'; } } class A extends Base { public function testSelf() { echo self::$var; } public function testParent() { echo parent::$var; } public function setSelf() { self::$var = 'self'; } public function setParent() { parent::$var = 'parent'; } public static function testStaticFun() { parent::testStaticFun(); echo 'over'; } } $objA = new A(); $objA->testSelf(); // var $objA->testParent(); // var $objA->setSelf(); $objA->testSelf(); // self $objA->testParent(); // self echo Base::$var; // self $objA->setParent(); $objA->testSelf(); // parent $objA->testParent(); // parent echo Base::$var; // parent Base::testStaticFun(); // func A::testStaticFun(); // func over </code>
所以 php 中静态的继承究竟是什么情况?是不是和其他语言比如 java 在静态继承的行为上有区别?父类的静态属性和方法会不会被覆盖?继承之后静态属性是不是只有一份?继承实现的原理是什么?
分成几点说吧:
1.静态成员可以使用 访问控制关键字修饰,可以被继承和重写
也就就说子类可以继承到父类的静态变量、方法...遵循“关键字”规则
2.如果子类没有重写,那么子类调用的实际是父类的静态方法
这个也很简单明了,继承的基本规则,没什么好解释的
3.静态成员持有者是类不是对象,所以类的多个实例共享同一个静态属性的,在一个实例中修改静态属性会影响到另一个实例中的静态属性
这个就是重点了,好好理解下,单列模式也是利用这个特性。
所以代码中 self::$var 和 parent::$var 其实指向的都是父类中的$var!
最后举个栗子:
单例模式下,$var你可以理解为数据库连接,父类生成一个连接后,继承的子类直接使用这个连接即可连接使用数据库。
但是如果子类自己生成一个连接$var,那么使用的时候就要区分是self::$var还是parent::$var,因为俩个值可能不一样,连接的数据库也不一样。万一是主从呢。哈哈。
happy coding~
此类问题我在这里已经回答过好几遍了,比如这个。你看下就明白了。
没错,静态属性只有一份!
所以使用静态属性写单例模式的时候一定要小心又小心。