何时需要使用静态方法?

时间:2013-08-16 06:20:51

标签: php

我认为通常我们使用静态方法,因为我们不需要实例化对象。我们可以使用className::staticFunction来调用静态方法,今天发现了:

test1.php

<?php
class Foo { 
    static public function helloWorld() {
        print "Hello world " ;
    }
}
Foo::helloWorld();

test2.php

<?php
class Foo { 
    public function helloWorld() {
        print "Hello world " ;
    }
}
Foo::helloWorld();

问题:

以上两个脚本都有效。我们没有将函数声明为static,我们仍然可以使用className::staticFunction来调用函数。为什么我们需要使用静态方法?

6 个答案:

答案 0 :(得分:5)

  

我们没有将函数声明为static,我们仍然可以使用className::staticFunction

您可能没有注意到的是PHP抱怨第二种类型的调用:

  

PHP严格标准:不应在第1行的php shell代码中静态调用非静态方法Foo::helloWorld()

     

严格标准:不应在第1行的php shell代码中静态调用非静态方法Foo::helloWorld()

要使这些通知可见,您需要使用-1ini_set()配置文件将error_reporting的值设置为php.ini;顺便说一下,这是在开发过程中推荐的。

<强>结论

静态调用的函数应声明为static function xyz()

<强>更新

顺便说一句,使用范围解析运算符::并不一定意味着您正在进行静态调用;考虑这个例子:

class Foo 
{ 
    public function helloWorld() 
    {
        print "Hello world ";
    }

    public function doSomething()
    {
        self::helloWorld();
    }
}

$f = new Foo;
$f->doSomething();

这是有效的,因为使用self::而不是Foo::不会更改调用“模式”(除非您调用的方法定义为static)。

答案 1 :(得分:2)

静态方法的“问题”是它们的调用方式:

Foo::bar();

对静态方法的任何调用都必须是硬编码的,不能轻易替换。与:比较:

$foo->bar();

$foo这里是变量,这意味着可以替换bar()的确切对象和实现。这对依赖注入很重要,也是依赖注入的基础。

您将使用静态方法:

  • 首先是您不需要单个对象实例的情况
  • 在实例化对象之前需要做的任何事情
  • 替代对象构造函数,例如DateTime::createFromFormat()而不是new DateTime
  • 幂等效用函数,您100%确定永远不需要替换或嘲笑

可能在其他场景中使用静态函数,但这些是要点。您需要注意,声明一个静态方法意味着您需要静态调用它,这意味着它的调用时间使用不能真正改变。关于这一主题的长期条约,请阅读How Not To Kill Your Testability Using Statics

答案 2 :(得分:0)

从上面的例子 test1.php

由于您添加了静态关键字,

helloworld()函数无法 覆盖重载

但是在第二个例子中, test2.php

helloworld()功能可以 重载覆盖

插图:1 (作品)

<?php
class Foo {
    function helloWorld() {
        print "Hello world " ;
    }
}

class Foo1 extends Foo
{
    function helloWorld()
    {
        echo "Foo's World";
    }
}
$Foo1 = new Foo1();
$Foo1->helloWorld(); //Foo's World

插图:2(失败)

  

无法使静态方法Foo :: helloWorld()非静态

<?php
class Foo {
    static function helloWorld() {
        print "Hello world " ;
    }
}

class Foo1 extends Foo
{
    function helloWorld()
    {
        echo "Foo's World";
    }
}
$Foo1 = new Foo1();
$Foo1->helloWorld();

答案 3 :(得分:0)

一个简单的hello world程序可能无法显示出很大的区别是静态vs的使用而不是看看这个类

class foo {


    private $a = 1;

    private static $b = 2;


    public function foobar()
    {
        echo $this->a;
    }

}
如果您静态拨打foobar,则上述课程中的

将无法解决$this->a

答案 4 :(得分:0)

PHP很有趣,但我通常会有一个实用程序类,它接受事物的参数来执行逻辑并返回。像这样的东西不需要实例化的类。由用户/开发人员正确调用方法(读取:使用正确的方法访问器)。

答案 5 :(得分:0)

当您处理基于OOP的大型项目时,您无疑将使用许多类(父类和子类)。这样做的一个不幸结果是,为了访问来自不同类的元素,必须手动传递每个类(或者更糟糕的是,将实例存储在全局变量中)。这可能令人沮丧,并且可能导致代码混乱和整体糟糕的项目设计。值得庆幸的是,可以从任何上下文(即脚本中的任何位置)访问静态元素,因此您可以访问这些方法,而无需将类的实例从对象传递到对象。

由于您不需要声明对象实例来访问静态元素,因此可以从不必要的声明中保存,以访问看似简单的函数。

静态元素在类的每个实例中都可用,因此您可以设置希望对类型的所有成员可用的值。