php 中 static 属性和方法的继承问题
网上关于静态属性和方法的继承问题,答案千奇百怪,干脆直接代码试了下:
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
所以 php 中静态的继承究竟是什么情况?是不是和其他语言比如 java 在静态继承的行为上有区别?继承实现的原理是什么?
其实遇到这个问题主要是因为解决 model 引用数据库驱动的问题,因为一个业务逻辑下来 model 可能被 new 很多出来(不同的 model ),本来是在 model 基类里的 __construct 调用 DBFactory 工厂类的静态方法返回一个唯一的驱动对象的(比如: DBFactory::getDriverInstance('pdo'))。
但是感觉多此一举,于是想抛掉这个工厂类,直接让 model 基类来做这个事情,这时候就遇到上面的问题了,如果不用静态直接 model 基类的 __construct new 一个比如 Pdo 对象,虽然 UserModel/PostModel 全局只会有一个,但这两个模型对象都会持有一个 Pdo 对象,并且不是同一个。
于是想到 model 基类里放一个 static $dbInstance , model 的 __construct 负责给这个属性赋值,如果说继承类是用的同一个 $dbInstance ,那么我的目标就可以实现了?
还是说干脆写一个类似 thinkphp 的 M() 方法,只不过我叫 DB(),主要是为了获取数据库驱动对象的,方法里内置 static 变量,这样是 100% 可以的,并且还能通过接收参数临时切换驱动(业务里遇到过 mysql 切 mongo 的场景)。
但是既然也到静态继承的问题,就想搞个明白!请前辈指教!
----------------------- 以下是精选回复-----------------------
答:PHP 的静态类型基本上可以理解为没有继承继承行为,静态属性该类的所有实例共用的。子类除非调用 parent 必须要用 parent ,否则修改就是自身的属性,不会影响父类的属性。如果父类方法中需要修改的是子类的静态属性,要用 static 关键字,而不要用 self , self 只会修改自身的属性,不会影响子类的属性。
答:你的方法是可行的,但是不建议这么做。
答:可以看看手册
http://php.net/manual/en/language.oop5.late-static-bindings.php
答:没见过静态成员参与继承。从生活习惯上也不符合习惯。继承的好处就是,可以通过派生类的一个实例的引用来访问基类成员。
而静态成员本来就可以用过类名直接访问。何须通过继承来多此一举。
0条评论