通常,如前所述,实例方法是更好的做法。这并不是说静态方法是完全邪恶的,它们只是有一个不同的和独特的目的。
请务必注意,在处理实例方法时,您使用的是对象,而静态方法使用的是类。使用静态方法时,您将无法访问实例通常可用的任何非静态属性。
以下代码为例:
class Foo
{
private $bar;
private static $tavern;
public function changeBar($value)
{
$this->bar = $value;
}
public function getBar()
{
return $this->bar;
}
public static function changeTavern($value)
{
self::$tavern = $value;
}
public static function getTavern()
{
return self::$tavern;
}
}
类具有静态属性和非静态属性 。Foo
$tavern
$bar
如果创建了 的实例,则所有属性和方法都可用于该对象。Foo
如果 静态引用,则只有属性、方法和方法可用于该类。Foo
$tavern
changeTavern()
getTavern()
让我们看一下下面的代码:
$foo = new Foo();
$foo->changeBar('Tipsy Turvy');
echo $foo->getBar(); // prints Tipsy Turvy
因为 是 的一个实例,所以它可以访问整个类。调用将修改属性。直接从静态方法更改属性将触发错误,因为该属性对对象而对类可用。$foo
Foo
changeBar()
$bar
$bar
$bar
// Calling this method would trigger an error
public static function changeBar($value)
{
$this->bar = $value; // PHP will crash and burn if you try this.
}
如果要从静态方法访问类属性,则还必须将这些属性声明为 static。这将在上述类的上下文中工作。您还会注意到,的实例在读取静态属性时没有问题。Foo
Foo::changeTavern('Stumble Inn');
echo Foo::getTavern(); // prints Stumble Inn
echo $foo->getTavern(); // also prints Stumble Inn
关于静态代码要记住的另一件事是,它的行为不像一个实例。当第一个实例构建时,两个属性都没有价值。如果要创建 另一个实例,您会发现这些属性中只有一个不再包含值。(我相信到现在为止,你可以猜到哪一个。Foo
$bar
$tavern
Foo
$anotherFoo = new Foo();
echo $anotherFoo->getBar(); // prints nothing
echo $anotherFoo->getTavern(); // prints Stumble Inn
echo Foo::getTavern(); // prints Stumble Inn
所以同样,静态代码意味着你直接使用一个类 - 实例意味着你正在使用一个对象。请务必注意,您编写的任何类型的类,如果打算对其具有某种状态,都应用作实例。
静态类可能有点难以调试和测试。测试可能会有问题,因为在创建新实例时静态属性不会更改。调试也可能很困难,因为静态属性的值在类的所有实例中都是相同的。在一个中进行更改,您将在所有这些更改中进行更改。跟踪哪个实例进行了更改是一件痛苦的事情。
打个比喻,使用像糖这样的静态类 - 谨慎地,只在必要时。
希望这有助于阐明这个话题。