PHP China | 中国开源之路 's Archiver

某个人 发表于 2008-11-14 01:25

静态成员扯到的一些疑问和大家探讨一下

静态成员我以前是这样理解的
在类里面定义个变量为静态,然后在类中引用他。这个值是针对整个类的,而不是单一的实例。但今天又学到了几个关于静态成员的深入理解(下面的英文都是从书上摘抄下来的。):
The paamayim nekudotayim symbol, also known as the scope resolution operator, is specified by a double colon (::) and is used to access different scope levels within classes. This operator takes a scope on the left and a member on the right.
You can use two magic scopes with the scope resolution operator: self and parent. Additionally, PHP 6 introduces static scope.
The code shown earlier in Listing 2-2 illustrates access to the self scope. This scope refers to the current class, but unlike $this, it does not refer to a specific instance of a class. It cannot be used outside a class and is not knowledgeable of its position in an inheritance tree. That said, self, when declared in an extended class, can call methods declared in a base class but will always call the overridden method!
最后讲述了在调用在被继承的类里面用self关键字,能够调用基类中的申明方法,也能调用重写后的方法。也就是说。Self关键字不仅仅只是像$this操作符一样只能指向本类的成员。而是能够在整个继承树中引用。因为他不是指向一个特殊的实例。而是指向整个类中的成员。书上提供的例子可以执行,但是debug报错。。可能是php6才引入的一个static scope概念吧。但是从理论上这个概念是可行的。
在子类中,如果想调用父类中的方法或者成员变量。可以使用parent关键字。这都是由于::这个生存操作符所决定的。左边是生存空间,右边是类的成员。Self是指向整个类中的任何成员。包括上面所说的继承树中也是可见。而parent的生存空间是这个类的父类中的所有成员和方法。
All of the prior examples use instances of classes to access methods. You may also pass a class name to the left of the :: operator to access a member statically and avoid needing to create an instance. This will save you writing instantiation code, and it can be more efficient, as each instance of a class takes up a small amount of system resources
有一个更好的方法来给类做实例引用。就是通过在::的左边写上类的名字去访问静态成员。这也将保证写出实例化的代码,并且能够更有效率。因为每一个类的实例引用都将占小量的系统资源。
终于明白了为什么$this->变量名不需要$,而self::访问静态变量需要$
Note again the use of the $ symbol when accessing myVariable via the :: operator. This is because PHP currently does not support the use of dynamic static variables—that is, variable variables that are static. When using $this->$variable, the member that is accessed is the value contained in $variable. Accessing a variable without the $ symbol will actually be looking for a class constant, and constants cannot be accessed via $this
当使用$this->$变量名的时候,是先查找$变量名所代表内容值。如果访问的变量没有$符号,将被自动的看做是一个类的常量,而常量是不需要通过$this引用的。
换句话说。整个过程应该是这样。$变量名是引用的一个值。而这个值由于不是通过$符号访问的,那么就会被当做是一个类的常量。但常量是不需要$this访问的。
可能还是有疑问。因为我们通常访问变量是$this->变量名。那为什么这里就没报错呢?我的理解是,上述说法是可以个可行的解释方案。因为在上述的$this->$变量名的解析过程中,多了一步查询$变量名中的内容。而这一步之后才是Accessing a variable without the $ symbol will actually be looking for a class constant, and constants cannot be accessed via $this
不知道我这样理解对不对。。。
上面这段英文中,that is, variable variables that are static.我的理解是动态变量是静态的。。。汗。。无法理解。。跪求大神的出现解释
另外的。。。php 6将引入迟绑定?点解?

slawdan 发表于 2008-11-14 02:11

This will save you writing instantiation code, and it can be more efficient, as each instance of a class takes up a small amount of system resources

楼主这句话翻译的不对。应该是:

这将让你不用写实例化(一个对象)的代码, 并且,这样更高效,因为每一个类的每个实例都会占用少量系统资源(而直接用类静态方法则因不需创建实例而节省了这些资源)。
---------------------------
This is because PHP currently does not support the use of dynamic static variables—that is, variable variables that are static.
这是因为,php不支持动态调用类的静态属性——由此,动态属性被映射到了静态属性上……
---------------------------
注解: 很绕口阿~
先解释一下动态属性。php中可以使用
[php]$hello = 'world';
$world = 'slawdan';
echo 'hello , ' . $$hello; // 输出: hello , slawdan
[/php]
这种方式来动态调用一个变量,这个$$hello就是一个 variable variables (动态变量)。这种方式也可以用于类的属性:
[php]
class A{
    public $foo = 'bar';
}

$a = new A();
$b = 'foo';
echo $a->$b; // 输出 bar
[/php]

这种方法就是动态调用属性~

由于php目前不支持静态属性的动态调用:
[php]
class A{
    static public $foo = 'bar';
    static public $b = 'you';
}

$a = new A();
$b = 'foo';
echo A::$b; // 输出 you
[/php]

注意到这里的$b不会被自动转为static属性的foo。所以,搞php那帮人就把这种书写格式,搞成了直接调用 A 的 静态属性 b 了……

这就是原文要讲的意思:动态调用静态属性(的写法),成了直接调用静态属性……

----------------------

php 5.3.0 + 和 php 6会有静态方法的迟绑定。意思是静态属性的处理会顺延绑定到派生类中……这个,如果你经常用 Singleton的话,就会知道。

[php]
class A{
     static protected $_instance = null;
    static public function getInstance(){
        if(null === self::$_instance)
             self::$_instance = new A();
        return self:$_instance;
    }
}

class B extends A{}

$b = B::getInstance();
[/php]

在没有迟绑定的版本中这样做,会失败……5.3+和6.0+则会得到一个 b 的单例。

某个人 发表于 2008-11-14 02:33

呃。。首先。我先反驳一下。我并没有翻译。。只是作为引证我的观点。。。汗一个。。然后再仔细看看你说的。。

某个人 发表于 2008-11-14 02:38

大哥解释得很清楚啊。
这样就是说。$this->$变量名是作为一中动态性的调用模式。
而self 是静态调用模式。暂时php不支持OO中动态方法或者类中调用静态方法活成员。
是这样么?
那就对了。。。其实是我头搞晕了。用OO中应该是符合的。
非静态的方法不能调用静态方法。self就是个静态的方法。你不可能加上$使他变成非静态的方法去调用静态的成员。ok。完全理解

[[i] 本帖最后由 某个人 于 2008-11-14 02:47 编辑 [/i]]

slawdan 发表于 2008-11-14 02:43

[quote]原帖由 [i]某个人[/i] 于 2008-11-14 02:38 发表 [url=http://bbs.phpchina.com/redirect.php?goto=findpost&pid=718608&ptid=90713][img]http://bbs.phpchina.com/images/common/back.gif[/img][/url]
大哥解释得很清楚啊。
这样就是说。$this->$变量名是作为一中动态性的调用模式。
而self 是静态调用模式。暂时php不支持OO中动态方法或者类中调用静态方法活成员。
是这样么? [/quote]

原文大意大概差不多基本没什么差错的话,是的…… -_-!!

顺便赞一下楼主的英文翻译,相当通顺阿~

[[i] 本帖最后由 slawdan 于 2008-11-14 02:47 编辑 [/i]]

某个人 发表于 2008-11-14 02:47

不是原文啊。。是一种个人的理解。刚才转到大哥你的回帖到我blog做记号回答的时候突然想到的。赶紧跑过来编辑帖子

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.