靜態

2016-10-06 20 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