【发布时间】:2012-06-03 01:33:36
【问题描述】:
我已经看到有两种不同的方式来访问一个类中的方法。行为上是否有任何差异,或者它们是否纯粹是同一操作的替代语法?
$a = new A();
$a->foo();
A::foo();
【问题讨论】:
-
了解什么是“静态方法”。
-
您似乎混淆了静态方法和实例方法。请看我的回答
标签: php oop scope-resolution
我已经看到有两种不同的方式来访问一个类中的方法。行为上是否有任何差异,或者它们是否纯粹是同一操作的替代语法?
$a = new A();
$a->foo();
A::foo();
【问题讨论】:
标签: php oop scope-resolution
您不能只使用其中一个。 :: 用于静态方法和变量,而-> 用于实例方法和变量。这是来自 C++ 语法的“启发”。
class A {
public function __construct() {}
public function foo() {}
}
$a = new A();
$a->foo();
// Or use the shorter "new A()->foo()";
// It won't return typeof(A), it will return what foo() returns.
// The object will still be created, but the GC should delete the object
或
class A {
public static function foo() {}
}
A::foo();
根据DCoder,::可以用于调用父方法,但我不确定。
class B {
public function __construct() {}
public function foo() {}
}
class A extends B {
public function __construct() {
// Code
parent::__construct()
}
public function foo() {
// Code
parent::foo()
}
}
【讨论】:
$this,您仍然会创建对象。 :)
$this,你仍然可以使用 $a = new A()->foo(),并且仍然不会丢失创建的对象实例
:: 还有一个更有效的用途——从子类 (parent::method()) 中相同方法的重载版本内部调用父类的方法。
当你这样做时
$a = new A();
您有一个名为 A 的对象类的实例。
这意味着您有一个特定的对象(具有自己的个性,属性中的具体值)。
因此,您可以使用以下表达式访问此对象的属性和调用方法:
$a->foo();
另一方面,
A::foo();
是访问驻留在类本身(在类的定义中)的属性和方法的正确方法。这些称为静态。
主要区别在于静态方法可以在创建该类的任何对象之前访问,即无需使用new 运算符。它们用于跨对象属性和对象范围的方法。
对象的实例(使用new 运算符创建)是类的真实副本,它们的属性可以有不同的值。对于相同的属性,同一类的两个对象可以在其中具有不同的值。在类的 static 部分中,所有对象都将具有相同的值和行为。
希望有所帮助!
【讨论】:
-> 将访问从类 A 实例化的特定对象的方法。
:: 是 范围解析运算符,它引用指定类的静态成员(在您的情况下为类 A)。
如果您没有注意到 -> 可以访问对象 $a 的方法,该对象 WAS 从类 A($a = new A();) 创建,但使用 :: 您可以访问静态方法(静态方法不需要访问对象)。
例如。
假设你有一个名为 Math 的类,它有一个静态方法 Add():
<?php
class Math{
// Note the 'static' keyword
public static function Add($arg1, $arg2){
return $arg1+$arg2;
}
}
?>
在这种情况下,您可以立即使用Add() 方法,而无需像这样创建Math 类的任何对象:
<?php
print Math::Add(2, 3);
?>
您使用:: 符号来访问Math 类的静态方法。使用 -> 符号没有意义,因为它用于访问从类创建的对象的方法。
所以:
<?php
class Math{
// Add() NO LONGER static
public function Add($arg1, $arg2){
return $arg1+$arg2;
}
}
?>
而你必须这样做:
<?php
$object = new Math();
$result = $object->Add(2, 3);
print $result;
?>
【讨论】:
使用 :: 运算符静态访问类。在这种情况下,没有类的实例作为对象。它用于不同的 OOP 设计模式,例如 Singleton 和 Factory 方法。访问它的范围几乎是全球性的,如果你不知道自己在做什么,可能会给你带来麻烦。
使用 -> 运算符意味着您正在访问实例化类的方法或变量。在这种情况下,范围在您实例化的特定对象内,并删除了该 全局 状态。
【讨论】:
如果foo() 是静态方法,您将使用class::foo() 访问foo() 方法。否则,您将使用object->foo() 作为实例方法。
【讨论】: