【问题标题】:Different ways to access methods访问方法的不同方式
【发布时间】:2012-06-03 01:33:36
【问题描述】:

我已经看到有两种不同的方式来访问一个类中的方法。行为上是否有任何差异,或者它们是否纯粹是同一操作的替代语法?

$a = new A();
$a->foo();

A::foo();

【问题讨论】:

  • 了解什么是“静态方法”。
  • 您似乎混淆了静态方法和实例方法。请看我的回答

标签: php oop scope-resolution


【解决方案1】:

您不能只使用其中一个。 :: 用于静态方法和变量,而-> 用于实例方法和变量。这是来自 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()
    }
}

【讨论】:

  • 值得注意的是,如果您在 A->foo() (第一个示例)中返回 $this,您仍然会创建对象。 :)
  • @damianb 注意到内存泄漏
  • ...不,事实并非如此。它不会泄漏;当对对象的所有引用都消失时,php 会将其 GC 遗忘。并且,如果没有,如果/当它在长时间运行的脚本上运行时,循环垃圾收集器将捕获它。我的观点是,如果你在 A->foo() 中返回 $this,你仍然可以使用 $a = new A()->foo(),并且仍然不会丢失创建的对象实例
  • :: 还有一个更有效的用途——从子类 (parent::method()) 中相同方法的重载版本内部调用父类的方法。
【解决方案2】:

当你这样做时

$a = new A();

您有一个名为 A 的对象类的实例

这意味着您有一个特定的对象(具有自己的个性,属性中的具体值)。

因此,您可以使用以下表达式访问此对象的属性和调用方法:

$a->foo();

另一方面,

A::foo();

是访问驻留在类本身(在类的定义中)的属性和方法的正确方法。这些称为静态

主要区别在于静态方法可以在创建该类的任何对象之前访问,即无需使用new 运算符。它们用于跨对象属性和对象范围的方法。

对象的实例(使用new 运算符创建)是类的真实副本,它们的属性可以有不同的值。对于相同的属性,同一类的两个对象可以在其中具有不同的值。在类的 static 部分中,所有对象都将具有相同的值和行为。

希望有所帮助!

【讨论】:

    【解决方案3】:

    -> 将访问从类 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 类的静态方法。使用 -&gt; 符号没有意义,因为它用于访问从类创建的对象的方法。

    所以:

        <?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;
    ?>
    

    【讨论】:

      【解决方案4】:

      使用 :: 运算符静态访问类。在这种情况下,没有类的实例作为对象。它用于不同的 OOP 设计模式,例如 Singleton 和 Factory 方法。访问它的范围几乎是全球性的,如果你不知道自己在做什么,可能会给你带来麻烦。

      使用 -> 运算符意味着您正在访问实例化类的方法或变量。在这种情况下,范围在您实例化的特定对象内,并删除了该 全局 状态。

      【讨论】:

        【解决方案5】:

        如果foo() 是静态方法,您将使用class::foo() 访问foo() 方法。否则,您将使用object-­&gt;foo() 作为实例方法。

        【讨论】:

          猜你喜欢
          • 2018-04-23
          • 2014-07-09
          • 1970-01-01
          • 2019-04-06
          • 2020-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-27
          相关资源
          最近更新 更多