- 测试 static:: 和 self:: 在继承中的行为差异 - 验证静态属性在不同子类中的独立性 - 检查静态方法重写和构造函数中的调用 - 覆盖 late static binding 的各种使用场景pull/1/head
parent
c8e22239bb
commit
a4bc4fcfc0
1 changed files with 131 additions and 0 deletions
@ -0,0 +1,131 @@ |
||||
--TEST-- |
||||
Early Static Binding - late static binding with static:: and self:: |
||||
--FILE-- |
||||
<?php |
||||
class ParentClass { |
||||
public static function who(): string { |
||||
return __CLASS__; |
||||
} |
||||
|
||||
public static function test_self(): string { |
||||
return self::who(); |
||||
} |
||||
|
||||
public static function test_static(): string { |
||||
return static::who(); |
||||
} |
||||
} |
||||
|
||||
class Child extends ParentClass { |
||||
public static function who(): string { |
||||
return __CLASS__; |
||||
} |
||||
} |
||||
|
||||
// Test with static properties |
||||
class Config { |
||||
protected static array $settings = []; |
||||
|
||||
public static function get(string $key): mixed { |
||||
return static::$settings[$key] ?? null; |
||||
} |
||||
|
||||
public static function set(string $key, mixed $value): void { |
||||
static::$settings[$key] = $value; |
||||
} |
||||
} |
||||
|
||||
// 在 main 中初始化不同的配置 |
||||
function test_static_properties() { |
||||
// DevConfig 使用自己的 settings |
||||
\DevConfig::$settings = ['dev' => true, 'debug' => true]; |
||||
var_dump(DevConfig::get('dev')); |
||||
var_dump(DevConfig::get('debug')); |
||||
|
||||
// ProdConfig 使用自己的 settings |
||||
\ProdConfig::$settings = ['prod' => true, 'debug' => false]; |
||||
var_dump(ProdConfig::get('prod')); |
||||
var_dump(ProdConfig::get('debug')); |
||||
} |
||||
|
||||
class DevConfig extends Config { |
||||
// 子类使用自己的属性 |
||||
} |
||||
|
||||
class ProdConfig extends Config { |
||||
// 子类使用自己的属性 |
||||
} |
||||
|
||||
// Test with static method override |
||||
class Factory { |
||||
protected static string $className = 'BaseClass'; |
||||
|
||||
public static function create(): object { |
||||
return new static::$className(); |
||||
} |
||||
|
||||
public static function getClassName(): string { |
||||
return static::$className; |
||||
} |
||||
} |
||||
|
||||
class UserFactory extends Factory { |
||||
protected static string $className = 'User'; |
||||
} |
||||
|
||||
class ProductFactory extends Factory { |
||||
protected static string $className = 'Product'; |
||||
} |
||||
|
||||
class User {} |
||||
class Product {} |
||||
|
||||
// Test in constructor |
||||
class Base { |
||||
public function __construct() { |
||||
echo "Base constructor\n"; |
||||
static::init(); |
||||
} |
||||
|
||||
public static function init(): void { |
||||
echo "Base init\n"; |
||||
} |
||||
} |
||||
|
||||
class Derived extends Base { |
||||
public static function init(): void { |
||||
echo "Derived init\n"; |
||||
} |
||||
} |
||||
|
||||
function main() { |
||||
// Test basic late static binding |
||||
var_dump(ParentClass::test_self()); // Should print "ParentClass" |
||||
var_dump(ParentClass::test_static()); // Should print "ParentClass" |
||||
var_dump(Child::test_self()); // Should print "ParentClass" (self refers to Parent) |
||||
var_dump(Child::test_static()); // Should print "Child" (static refers to called class) |
||||
|
||||
// Test with static properties |
||||
test_static_properties(); |
||||
|
||||
// Test with static method override |
||||
var_dump(UserFactory::getClassName()); |
||||
var_dump(ProductFactory::getClassName()); |
||||
|
||||
// Test in constructor |
||||
new Derived(); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(11) "ParentClass" |
||||
string(11) "ParentClass" |
||||
string(11) "ParentClass" |
||||
string(5) "Child" |
||||
bool(true) |
||||
bool(true) |
||||
bool(true) |
||||
bool(false) |
||||
string(4) "User" |
||||
string(7) "Product" |
||||
Base constructor |
||||
Derived init |
||||
Loading…
Reference in new issue