2013-03-29 235 views
4

我有一个只有静态方法扩展类的子类。我想让这个子类成为单例而不是静态的,因为原始开发者确实想要一个单例,但是使用了静态(显而易见,因为静态类中的每个方法都调用Init()函数(基本上是构造函数))。非静态调用静态方法

大部分父方法不需要在孩子被覆盖,但我想,以避免写这样的方法:

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

的时候我宁愿不要覆盖方法,只是使用:

$child->Load($id); 

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

+0

为什么不只是使用普通的旧PHP对象?没有所有的静态和单例废话你可能[不需要]头痛(http://stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323)。另外,是可测试的。毕竟,它被称为面向对象*而不是面向类。 – Gordon

+0

Singleton是一种设计模式。它使用一个“普通的旧”php对象,它只是意味着它有一个私有的构造函数和一个静态的GetInstance方法。它确保只存在一个对象的实例,但由于它有一个构造函数,所以不必在每个方法中初始化变量。 – Mike

+0

我知道单身是什么:)我所说的是:你不需要它。请参阅我的初始评论中的链接。你正在用静力学和单身生活让你的生活变得悲惨。 – Gordon

回答

9
  • 你能继承静态方法吗?

  • 你能重写静态方法?

是的,但只是作为PHP 5.3的做他们的工作,你所期望的:(即self结合实际的类,而不是它的定义类)http://www.php.net/manual/en/language.oop5.static.php

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

是的,但会丢失$this。你还没有得到警告,但也没有理由认为它是错误的。

+0

所以你推荐使用第一种方法,我覆盖并调用父级静态? – Mike

+1

如果您使用PHP5.3或更高版本,是的。此外,它覆盖*不覆盖。 – Halcyon

+11

你不会得到任何警告。只有在您静态调用非静态方法时,才会出现警告。 –

7

两部分答案。

首先,关于题目问题:非静态地调用一个静态方法是很好的; @ 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在他们的方法中做的是不调用静态方法。 (或者至少,它不一定是;我们看不到父实现)。关键是,使用父关键字不是一个静态调用。如果在扩展类中使用::运算符,则显式父类名称上的使用也不是静态调用。

为什么该文档链接如此奇怪地命名?这实际上是希伯来语。如果您遇到过与之相关的错误,您可能会观察到令人愉快的解析器错误代码T_PAAMAYIM_NEKUDOTAYIM