性状中的静态变量如何不';在PHP中,当在类内部使用时,它不会失去价值吗?
虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值? 让我们考虑下面的例子,性状中的静态变量如何不';在PHP中,当在类内部使用时,它不会失去价值吗?,php,oop,static,traits,Php,Oop,Static,Traits,虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值? 让我们考虑下面的例子, trait Test{ public static $var = 1; public static function increment(){ self::$var ++; var_dump(self::$var); } } Test::increment();//2 class Test2{
trait Test{
public static $var = 1;
public static function increment(){
self::$var ++;
var_dump(self::$var);
}
}
Test::increment();//2
class Test2{
use Test;
}
var_dump(Test2::$var);//2
Test2::increment();//3
这种行为在继承中是正确的,在继承中,子对象扩展父对象,因此子对象使用父对象静态变量,但是根据复制和粘贴应用的特性,这种行为如何工作和纠正
这是一个更新,为我的困惑添加了另一个原因, 如果静态值保留给特定的上下文,比如特定的类或函数,那么如何使用来自不同上下文(新类)的静态属性的更新值呢。 我的意思是,如果trait测试的上下文被称为例如Context1,而类Test2上下文被称为Context2,那么我如何在另一个上下文中访问第一个上下文的保留值?这与我们理解的方法背道而驰
更新3: 所有这些混淆都取决于use关键字是在类中导入trait成员还是从中复制/粘贴? 一种特质类似于一个类,但只用于分组 以细粒度和一致的方式提供功能。这是不可能的 单独实例化一个特征。这是对传统文化的补充 继承并支持行为的横向组合;就是, 类成员的应用程序,无需继承 您不能单独实例化一个Trait,也不能定义Trait使用的属性,因为它们会发生冲突,这是因为Trait将此功能“添加”到您要将其附加到的类中 虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值 trait有自己的上下文,与使用trait的类无关,至少对于静态属性是这样。如果类使用具有静态属性的trait,则该类将获得自己的上下文,即“自己的”静态属性,初始值从trait复制:
trait T {
// '$staticProp' exists in the context of T
public static $staticProp = "in T\n";
}
// Without the need of a class that implements the trait, you can already access its value explicitly:
echo T::$staticProp; // in T
class A {
// Now 'A' gets its own '$staticProp', the initial value is copied from the context of the trait 'T'
use T;
}
// Now you can access 'A's '$staticProp' explicitly:
echo A::$staticProp; // in T
// Now we can explicitly change the value of 'A's '$staticProp'. Because 'A' has its own context, 'T::$staticProp' stays untouched:
A::$staticProp = "in A\n";
echo A::$staticProp; // in A
echo T::$staticProp; // in T
这是一个更新,以增加另一个原因的困惑,我有。。。我的意思是,如果trait测试的上下文被称为例如Context1,而类Test2上下文被称为Context2,那么我如何在另一个上下文中访问第一个上下文的保留值 如我所示,您始终可以使用类/特征名称和范围解析运算符(
:
)访问特定上下文的静态属性:
所有这些混淆都取决于use关键字是在类中导入trait成员还是在复制/粘贴 我认为理解这种行为的最佳方式如下:
让我们考虑下面的例子,
trait Test{
public static $var = 1;
public static function increment(){
self::$var ++;
var_dump(self::$var);
}
}
Test::increment();//2
class Test2{
use Test;
}
var_dump(Test2::$var);//2
Test2::increment();//3
以下是您的示例中发生的情况:
trait Test {
public static $var = 1;
public static function increment() {
self::$var++;
var_dump(self::$var);
}
}
// This will increment '$var' in the context of trait 'Test'
Test::increment(); // 2
// Access '$var' of trait context 'Test':
var_dump(Test::$var); // 2
class Test2 {
// Members of 'Test' are copied with current values (2) in the context of class 'Test2'
use Test;
}
// Access '$var' of class context 'Test2':
var_dump(Test2::$var); // 2
// This will increment '$var' in the context of class 'Test2'
Test2::increment(); // 3
// '$var' of trait context 'Test' has not changed:
var_dump(Test::$var); // 2
对于类,子类包括其父类的上下文:
class A {
public static $staticProp = "I am in debt\n";
}
class B extends A {}
echo A::$staticProp; // I am in debt
echo B::$staticProp; // I am in debt
A::$staticProp = "Even more debts\n";
echo A::$staticProp; // Even more debts
echo B::$staticProp; // Even more debts
B::$staticProp = "Paid debts, now debt-free\n";
echo A::$staticProp; // Paid debts, now debt-free
echo B::$staticProp; // Paid debts, now debt-free
self
如果我们试图访问继承的成员,则通常引用它所使用的类或其父类:
class A {
public static $aProp = 0;
}
class B extends A {
public static $bProp = 0;
public static function setProps() {
// Because B has a non inherited property '$bProp' 'self' will reference the context of class 'B':
self::$bProp = 12;
// Because B inherits a property '$aProp' 'self' will reference the inherited context of class 'A':
self::$aProp = 23;
}
public static function printProps() {
echo 'self::$bProp: ' . self::$bProp . "\n";
echo 'self::$aProp: ' . self::$aProp . "\n";
}
}
B::setProps();
B::printProps();
// self::$bProp: 12
// self::$aProp: 23
A::$aProp; // 23
B::$aProp; // 23
// Again 'A' and 'B' share the same context:
A::$aProp = 0;
echo B::$aProp; // 0
当使用traitsself
时,引用traits上下文或复制的类的独立上下文。这就是您的示例中发生的情况:
trait Test {
public static $var = 1;
public static function increment() {
self::$var++;
var_dump(self::$var);
}
}
// This will increment '$var' in the context of trait 'Test'
Test::increment(); // 2
// Access '$var' of trait context 'Test':
var_dump(Test::$var); // 2
class Test2 {
// Members of 'Test' are copied with current values (2) in the context of class 'Test2'
use Test;
}
// Access '$var' of class context 'Test2':
var_dump(Test2::$var); // 2
// This will increment '$var' in the context of class 'Test2'
Test2::increment(); // 3
// '$var' of trait context 'Test' has not changed:
var_dump(Test::$var); // 2
我不理解你回答的所有方面,但根据我所理解的,问题不在于trait是一个具有附加或更少特性的类,问题在于我们没有使用继承来避免丢失静态属性的上下文值,我们只是在trait之间复制/粘贴属性和方法,那么,这种行为是如何复制旧的静态值的呢?我将对我的问题进行编辑,为我的困惑添加另一个证据。当一个特征具有静态属性时,这个答案根本不能回答关于不同背景的问题。。。