簡體   English   中英

靜態調用和非靜態調用非靜態方法之間的區別

[英]Difference between calling a non-static method statically and not statically

給出以下代碼:

<?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()之間有什么區別嗎?

恕我直言,如果您從班級內部調用它,沒有任何區別。

但是 ,如果從類外部調用它,則需要首先實例化以調用非靜態方法。

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

靜態:( PHP 7棄用

$var = MyExtendedClass::print();

在PHP 7上,您需要在方法上使用Static關鍵字,因此可以對其進行靜態調用。 全面參考

聲明為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::調用函數在對象上下文中調用它。

手冊中只有以下含糊段落可用於::運算符:

從類定義之外引用這些項目時,請使用類的名稱。

從PHP 5.3.0開始,可以使用變量來引用類。 變量的值不能是關鍵字(例如self,parent和static)。

似乎在類::外部始終是靜態操作的,而$f::代替了類的名稱。 但是,在對象上下文中, ::保留了上下文,可能會啟用對parent::調用的正確操作,這顯然應該保留對象上下文。

在您給的示例中,“否”沒有區別。

盡管在大多數情況下完全不同,但是由於在非靜態中您正在打印對象的當前數字值,該值可能已更改(可以調用任何設置方法或類似方法)。

而對於靜態調用,它將始終打印相同的值(在范圍中聲明的默認值100)。

簡短的答案是: $instance::method(…) (其中$instance是類實例,而不是字符串) 似乎等效於get_class($instance)::method(…) (在您的情況下,它表示MyExtendedClass::print() )。

當您調用SomeClassName::method(…)method是否接收$this的事實是零星的。 這取決於您從何處調用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM