【发布时间】:2015-03-05 13:56:15
【问题描述】:
考虑以下几点:
class A
{
public static function bark()
{ echo 'woof'; }
}
class B extends A
{
public static function speak()
{ echo 'hello'; }
}
A::speak();
// Fatal error: Call to undefined method A::speak()
应该如何使用您需要在该类中全局可用的方法扩展一个类,该类中的方法尚不知道,但在运行时加载,具体取决于您的应用程序的流程?
是的,我们可以创建traits 并将use 放入类中,例如:
trait B
{
public static function speak()
{ echo 'hello'; }
}
class A
{
use B;
public static function bark()
{ echo 'woof'; }
}
A::speak();
// hello
- 但是
use B不会被动态调用,因此您必须使用每个可用的新特征手动更新 A 类。 这太荒谬了,为什么要强迫开发人员打破他们的大脑来尝试完成如此简单的事情?
有人知道如何以干净的方式完成此操作吗?我的意思是我通过使用单例、命名空间、回调和作品看到了一些令人印象深刻的方法,但在每种情况下,它都需要比实际需要的更多的代码和重复性编程。 要么,要么我完全错过了船哈哈! 在此先感谢您的帮助,我们将不胜感激并慷慨投票。
【问题讨论】:
-
简而言之,因为
B扩展了A,它继承了As方法,但A没有扩展B,所以它没有继承Bs方法;因此B::bark()会起作用,A::speak()不会——正如你所发现的。这只是静态方法的问题,因为它们属于类,而不是从该类实例化的任何对象。 -
我知道“使用全局变量”是不受欢迎的,我同意,但这与它的使用方式有关。在这种情况下 - 将“辅助功能”专门分组到需要的内容,而不是“以防万一”一次加载所有内容。话虽如此,类中的属性和方法可以是私有的并最终声明,有效地“保护”了类及其方法。此外,系统可以编写一个“用户权限系统”,只允许每个用户使用此类类,并且应用程序可以是用户本身,并且都可以分别包含在命名空间中。
-
静态方法有一席之地——不仅仅是“使用全局变量”。例如,假设您创建了一个
Email类,并在其中有一些方法用于验证或其他。验证方法是实例方法是有意义的,因为它们适用于该对象中保存的电子邮件数据。现在,假设您要添加一个将应用于实例化的每个 电子邮件对象的黑名单。在这种情况下,使用静态方法是有意义的。使用静态方法,黑名单将在内存中保存一次,对于类,使用实例方法,每个电子邮件对象都会将黑名单保存在内存中。 -
“使用未知的方法,但在运行时加载,具体取决于应用程序的流程” – 我怀疑这实际上是个好主意……这听起来像是通向 God Object 的路径,它将在不同的上下文中做各种各样的事情——这通常是不可取的。但是你的 A/B 和吠叫/说话的“例子”太笼统了,很难判断你是否正在尝试实现一些真正有意义的东西,或者你是否已经完全偏离了正确的道路。
-
听起来像一个糟糕的设计模式。很可能还有另一种方式,但如果没有更具体的例子,就很难告诉你是什么。
标签: php inheritance static