【问题标题】:Calling static method non-statically非静态调用静态方法
【发布时间】:2013-03-20 09:04:16
【问题描述】:

我有一个子类,它扩展了一个只有静态方法的类。我想让这个子类成为单例而不是静态的,因为最初的开发人员真的想要一个单例,但使用了静态(很明显,因为静态类中的每个方法都调用 Init() 函数(基本上是构造函数))。

父级中的大多数方法不需要在子级中覆盖,但我想避免编写这样的方法:

public function Load($id)
{
     return parent::Load($id);
}

当我根本不想覆盖该方法而只使用时:

$child->Load($id);

是否可以非静态地调用静态方法?是否可以使用实例对象扩展静态对象?我知道我可以试一试,它可能会奏效(PHP 非常宽容),但我不知道是否有什么我应该担心的。

【问题讨论】:

  • 为什么不使用普通的旧 PHP 对象?对于您可能don't need 的所有静态和单例废话,您不必头疼。另外,是可测试的。毕竟,它被称为面向对象,而不是面向类。
  • 单例是一种设计模式。它使用一个“普通的旧” php 对象,它只是意味着它有一个私有构造函数和一个静态 GetInstance 方法。它保证了一个对象只存在一个实例,但由于它有一个构造函数,你不必在每个方法中都初始化变量。
  • 我知道单例是什么 :) 我的意思是:你不需要它。请参阅我最初评论中的链接。静态和单身让你的生活变得悲惨。

标签: php oop static-methods


【解决方案1】:
  • 你能继承静态方法吗?

是的

  • 你能覆盖静态方法吗?

是的,但只有从 PHP 5.3 开始,它们才能像您期望的那样工作:http://www.php.net/manual/en/language.oop5.static.php(即self 绑定到实际的类,而不是它定义的类)。

  • 是否可以非静态调用静态方法?

是的,但会丢失$this。您(还)没有收到警告,但也没有真正的理由将其称为错误的方式。

【讨论】:

  • 所以你推荐使用第一种方法,我覆盖并调用父静态?
  • 如果您使用的是 PHP5.3 或更高版本,可以。此外,它是覆盖*而不是覆盖。
  • 您不会收到任何警告。只有在静态调用非静态方法时才会出现警告。
  • 现在我要哭了,因为上帝一定在我们的项目中杀死了很多小猫:(
  • 没有小猫因此而死,恰恰相反是完全错误的!
【解决方案2】:

两部分答案。

首先,关于名义上的问题:非静态调用静态方法非常好; @SamDark 的评论是正确的。它不会产生警告,也不会导致任何小猫谋杀。试试看:

<?php

class test {
    public static function staticwarnings(){
        echo "YOU ARE (statically) WARNED!\n";
    }
}

error_reporting(E_ALL);

$test = new test();
echo "\n\ncalling static non-statically\n";
$test->staticwarnings();

如果您在该静态方法中有一个实例引用$this,那么您将收到一个致命错误。但不管你怎么称呼它都是真的。

再一次,没有警告,也没有任何小猫被杀。


答案的第二部分:

从重写的子类调用重写的父函数需要名为 "scope resolution" 的东西。 OP 在他们的方法中所做的不是调用静态方法。 (或者至少,它不必是;我们看不到父实现)。关键是,使用 parent 关键字不是静态调用。在显式父类名称上使用 :: 运算符也不是静态调用,如果它是从扩展类中使用的。

为什么那个文档链接的名字这么奇怪?它的字面意思是希伯来语。如果您曾经遇到过与之相关的错误,您可能已经观察到了命名愉快的解析器错误代码T_PAAMAYIM_NEKUDOTAYIM

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    相关资源
    最近更新 更多