【问题标题】:Accessing child variables from the super class without instanciation从超类访问子变量而不实例化
【发布时间】:2009-02-03 23:27:49
【问题描述】:

我正在尝试通过父类访问子类中的成员变量,而无需实例化。

这是我的尝试之一,但B::getStatic()Access to undeclared static property 失败。

是否有另一种解决方案,可能没有静态?

class A {

    static public function getStatic() {

        return self::$myStatic;

    }

}

class B extends A {

    public static $myStatic = 5;

}

class C extends A {

    public static $myStatic = 6;

}

var_dump(B::$myStatic);
var_dump(B::getStatic());

var_dump(C::$myStatic);
var_dump(C::getStatic());

【问题讨论】:

  • 您是否尝试将 A 的 mystatic 设置为某个值以查看会发生什么?
  • 是的。它很好地引用了 A 中的静态,而不是 B。我明白为什么这是一个问题,因为 A 可能无法看到 B 的静态。我在问是否有其他方法可以做到这一点?
  • 哈哈大家都被否决了!

标签: php oop static


【解决方案1】:

您遇到的概念称为“后期静态绑定”。在 PHP 5.3.0 之前,不支持此功能。

如果您运行的是 5.3.0 或更高版本,请更新 getStatic() 方法:

静态公共函数 getStatic() {

return static::$myStatic;

}

【讨论】:

    【解决方案2】:

    其他人是对的,因为变量在编译时不存在,所以你的代码无法完成。

    做这样的事情的方法通常是使用一个抽象类(在 PHP5 及更高版本中可用,看起来像)。

    A 类是抽象类,并且有一个 getStatic() 函数。类 B 和 C 将扩展 A 并具有 getStatic() 函数的定义。这样,当您调用 getStatic() 时,您将获得子类定义的值,因为 A 中没有定义。

    这种方法的注意事项是您不能实例化 A,因为它是抽象的。您总是必须制作 B 或 C(或其子类)。

    您还可以在 A 中创建一个 setter,并让子类使用它来设置值(而不是“=”)。这将让您实例化 A 并且它可以在需要时设置值。或许可以将setter设为私有,这样就不能直接调用了,不知道子类能不能在PHP中使用私有函数。

    【讨论】:

      【解决方案3】:

      函数和变量的声明不匹配。

      要么你需要把函数的声明移到 B

      将变量的声明移到A。

      【讨论】:

      • 我需要将变量保留在 B 中,将函数保留在 A 中。是否有另一种解决方法,也许没有静态?
      • 我不知道,这是面向对象编程的基础知识。
      【解决方案4】:

      B 类从 A 类继承属性,而不是相反。

      你为什么不像你的例子那样使用B::$myStatic

      【讨论】:

      • 因为我是从 A 访问变量。
      • 只要课程可用,从哪里访问它并不重要。
      • 类 A { function get() { B::$myStatic; }} } 不起作用,因为当我调用 get() 时我不知道“B”是什么
      • 父类不知道其他类是否以及从它那里继承了什么。你必须告诉它。
      【解决方案5】:

      您必须将 myStatic 移动到 A 中。您在 A 中的方法 getStatic 无法访问 A 中不存在的变量。

      【讨论】:

        【解决方案6】:

        来自PHP manual

        对当前类的静态引用 像 self::__CLASS__ 已解决 使用函数所在的类 属于,正如它被定义的地方:

        因此,因为该方法是在 A 中定义的,所以当您在 BC 上调用 getStatic() 时,它会尝试返回不存在的 a::$myStatic。即使它确实存在,您也只能取回该值,而不是子类中的任何覆盖值。

        一种解决方案是后期静态绑定,但这仅在尚未发布的 PHP 5.3 中可用。

        【讨论】:

          【解决方案7】:

          $myStatic 必须在 A 类中声明为静态:参见 here

          【讨论】:

            【解决方案8】:
            class A {
                public static $myStatic = 5;
            }    
            class B extends A {
                public static $myStatic = 3;
            }
            class C extends A {
                public static $myStatic = 1;
            }
            

            然后只需使用 B::$myStatic ...

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-01-26
              • 1970-01-01
              • 1970-01-01
              • 2021-04-21
              • 1970-01-01
              • 2010-10-23
              • 2012-08-20
              相关资源
              最近更新 更多