静态

2016-10-06 18 views
1

考虑下面的代码:静态

<?php 
class MyClass { 
    public function print() { 
     echo $this->number . "\n"; 
    } 

    public static function staticPrint() { 
     echo "staticPrint\n"; 
    } 
} 

class MyExtendedClass extends MyClass { 
    protected $number = 100; 

    public function extendedPrint() { 
     $this->print(); 
     $this::print(); // What's the difference? 
     $this->staticPrint(); // Why is this allowed? 
     $this::staticPrint(); 
     echo "Print done...!\n"; 
    } 
} 

$myExtendedClass = new MyExtendedClass(); 
$myExtendedClass->extendedPrint(); 

与下面的输出:

100 
100 
Print done...! 

$this->print()$this::print()之间有什么区别?

+1

http://stackoverflow.com/questions/4361598/php-static-and-non-static-functions-and-objects – salih0vicX

+0

可能:http://stackoverflow.com/a/9207510/ 398939? –

+0

'$ this-> print()'和'$ this :: print()'之间没有区别。但是'$ var-> print()'和'$ var :: print()'之间存在(甚至在类内部)。请参阅[我的答案](http://stackoverflow.com/a/39891561/1421194)。 – Sasha

回答

1

恕我直言,如果你从你的班级中的中调用它,没有任何区别。

但是,如果你从你的类的外部调用它,你需要首先实例化来调用非静态方法。

$var = new MyExtendedClass; 
$var->print(); 

静态:(上不再支持PHP 7

$var = MyExtendedClass::print(); 
在PHP 7

,你需要在你的方法Static关键字,所以它可以静态调用。 Full reference

+0

'$ var = MyExtendedClass :: print();'您正在静态调用一个非静态方法,在PHP 7.0中'$ this'将会是未定义的。 – zer0uno

+0

@欢迎:我承认,只是更新了我的答案。 –

+0

不,有区别。请参阅[我的答案](http://stackoverflow.com/a/39891561/1421194)。 – Sasha

0

在你给No的例子中,没有区别。

虽然在大多数情况下完全不同的,因为在非静态要打印的对象,这可能已经改变的当前数值(任何方法或类似的可以称为)。

而用静态调用它总是打印相同的值(100在范围内声明的默认值)。

1

被声明为static的方法将总是被静态调用:

public static function bar() { var_dump($this); } 

调用此方法哪种方式,它会导致:

Fatal error: Uncaught Error: Using $this when not in object context 

(或其变型取决于您的PHP版本)

功能不是static关键字的行为......不同:

class Foo { 
    public function bar() { var_dump($this); } 
} 

$f = new Foo; 
$f::bar(); 
Deprecated: Non-static method Foo::bar() should not be called statically 
Fatal error: Uncaught Error: Using $this when not in object context 

调用外部功能实际调用它静态。

class Foo { 
    public function bar() { var_dump($this); } 
    public function baz() { $this::bar(); } 
} 

$f = new Foo; 
$f->baz(); 
object(Foo)#1 (0) { 
} 

经由$this::调用函数中的对象上下文调用它。

手动只有these vague paragraphs提供了::操作:

当从类的外部引用这些项目,请使用类的名称。

从PHP 5.3.0开始,可以使用变量来引用类。变量的值不能是关键字(例如self,parent和static)。

看来,一类::外面总是静态地运行,并且$f::替代类的名称。但是,在对象上下文中,::保留上下文,可能会启用调用的正确操作,这显然应该保留对象上下文。

0

简短的回答是: $instance::method(…)(其中$instance是一个类的实例,而不是字符串)似乎等同于get_class($instance)::method(…)(在你的情况下,意味着MyExtendedClass::print())。

当您拨打SomeClassName::method(…)时,method是否收到值为零的事实是零星的。这取决于你从什么地方拨打SomeClassName::method(…)。从SomeClassName或其后代的相同或其他方法调用SomeClassName::method(…)将导致$this从呼叫的地方传递到method;否则method可能不会收到任何$this值。

因此,当您拨打$instance::method(…)时,method可能会收到或不会收到$this值。如果它收到一个$this值,这将是从调用的地方$this值,但不是$instance(尽管它们可能重合,做$this::method(…)$instance = $this; …; $instance::method(…)时)。

http://sandbox.onlinephpfunctions.com/code/93d4ea2dd47dbc2c5ed338a96ca4d00d4ffef77b