PHP – 静态vs实例方法

我有点困惑,因为我在 PHP中没有太多的OOP经验.我总是听说使用实例方法比使用静态方法更好.为什么?

我需要一个深刻的答案.

例如,为什么下面这个应该用instance方法呢?

控制器:

public function getProperty($id){
        $property = Property::getProperty($id);
        return $property;
}

模型:

public static function getProperty($id){
        //$query = DB::table('properties')...
        //Some Code;
        return $query;         
}

我正在阅读关于setter / getter,实例vs静态等等.但是我需要一个完整的答案来了解事情的原因和原因.

一般来说,正如你已经说过的,实例方法是更好的做法.这并不是说静态方法是彻头彻尾的,它们只是具有不同而独特的目的.

重要的是要注意,当处理实例方法时,你正在使用一个对象,而使用静态方法你正在使用一个类.当使用静态方法时,您将无法访问通常可用于实例的任何非静态属性.

以下列代码为例:

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.
}

如果要从静态方法访问类属性,那么这些属性也必须声明为静态.这将在上述类的上下文中工作.您还会注意到,Foo的一个实例在读取静态属性时没有问题.

Foo::changeTavern('Stumble Inn');
echo Foo::getTavern(); //prints Stumble Inn
echo $foo->getTavern(); //also prints Stumble Inn

关于静态代码的另一件事是它不像一个实例.当Foo的第一个实例被建立了两个属性$bar和$小酒馆没有价值.如果要创建另一个Foo实例,您将发现只有其中一个属性不再包含值. (我现在肯定可以猜到哪一个.)

$anotherFoo = new Foo();
echo $anotherFoo->getBar(); //prints nothing
echo $anotherFoo->getTavern(); //prints Stumble Inn
echo Foo::getTavern(); //prints Stumble Inn

所以再次,静态代码意味着你正在直接使用一个类 – 实例意味着你正在使用一个对象.重要的是要注意,你写的任何类型的类,打算有某种状态,应该被用作一个实例.

静态类可能有点难以调试和测试.测试可能是有问题的,因为创建新实例时静态属性不会更改.调试也可能很困难,因为静态属性的值在类的所有实例中都相同.改变一个,你会在所有这些变化.跟踪哪个实例发生变化是一个痛苦.

以隐喻的方式说话,只要在需要的时候,就像糖一样使用静态类.

希望有助于阐明这个话题.

相关文章

Hessian开源的远程通讯,采用二进制 RPC的协议,基于 HTTP 传输。可以实现PHP调用Java,Python,C#等多语...
初识Mongodb的一些总结,在Mac Os X下真实搭建mongodb环境,以及分享个Mongodb管理工具,学习期间一些总结...
边看边操作,这样才能记得牢,实践是检验真理的唯一标准.光看不练假把式,光练不看傻把式,边看边练真把式....
在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较。 echo与print的区别: (...
在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring exte...
变量是用于存储数据的容器,与代数相似,可以给变量赋予某个确定的值(例如:$x=3)或者是赋予其它的变...