受保护的静态成员变量

15

我最近一直在处理一些类文件,发现成员变量以受保护的静态模式设置,例如 protected static $_someVar,并且通过 static::$_someVar 进行访问。

我理解可见性的概念,并知道将某些内容设置为受保护的静态内容可以确保成员变量只能在超类或派生类中被访问,但我能否仅在静态方法中访问受保护的静态变量呢?

谢谢

2个回答

45

如果我理解正确,你所指的是被称为静态延迟绑定的东西。如果你有这样的代码:

class A {
   protected static $_foo = 'bar';

   protected static function test() {
      echo self::$_foo;
   }
}

class B extends A {
   protected static $_foo = 'baz';
}

B::test(); // outputs 'bar'

如果你将 self 改为:

echo static::$_foo;

然后执行:

B::test(); // outputs 'baz'

因为self指的是定义$_foo的类(A),而static则引用运行时调用它的类(B)。

当然,在静态方法以外(即对象上下文)仍然可以访问静态受保护成员,尽管可见性和范围仍然很重要。


3
我认为在这个例子中,class B 应该是 "class B extends A"。 - Nathan Rambeck
1
@Nathan:好眼力(即使是几周以后)。已修复。谢谢! - netcoder

7

静态变量存在于类上,而不是类的实例上。您可以从非静态方法访问它们,类似地调用它们:

self::$_someVar

这个方法可行的原因是self是当前类的引用,而不是当前实例(例如$this)的引用。

举个例子:

<?
class A {
  protected static $foo = "bar";

  public function bar() {
    echo self::$foo;
  }
}

class B extends A { }

$a = new A();
$a->bar();

$b = new B();
$b->bar();
?>

输出结果为barbar。然而,如果您尝试直接访问它:

echo A::$foo;

然后PHP就会准确地提醒您尝试访问受保护的成员。

为什么要使用self而不是static?例如,self::$foo还是static::$foo。 - user275074
哦,是的,当在类外尝试时没问题,但我说的是在类方法内部访问它时。 - user275074
如果你定义了A->foo(),并且它调用self::$foo,那么它将返回在A中定义的静态$foo。如果你将A作为B的一部分进行子类化,然后调用继承的foo(),它将使用A中的$foo,即使你在B上定义了它。如果你使用static::$foo,那么它将使用在B上定义的$foo,如果你这样做了。 - Chris Heald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接