【问题标题】:Extending PHP static classes扩展 PHP 静态类
【发布时间】:2010-11-19 19:28:37
【问题描述】:

我已经在这方面苦苦挣扎了几天,我已经得出了一个结论,但是由于结论不是我想要的,所以在我放弃之前,我会尝试看看其他人怎么说。信仰最后死去……

假设我们有一个超类(称为“Super”)和一个子类(称为“Sub”)。

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo self::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

现在,您可能会期望,由于 Sub 扩展了 Super,Sub 现在将继承 Super 的所有方法,但是,它似乎只接收对 Sub 方法的引用。

我这样说是因为如果我打电话:

Sub::get_class_name();

输出是“Super”,而不是“Sub”。

如果我打电话:

Sub::get_title();

同样,输出是“super”,我什至在 Sub 中声明了 $title。

所以这意味着当我调用一个继承的静态函数时,函数的作用域将是超类,而不是被调用的那个(即使你打印回溯,它也会显示调用是在超类上进行的!! !),并且为了获得作为调用的子类的范围,我需要在该子类中重新声明该方法。 这样就违背了扩展类的目的,不是吗?

所以我的问题是,我可以扩展一个静态类,调用其中一个继承的方法并拥有子类的范围吗?或者至少能够识别它的类名? 如果没有,我为什么要扩展静态类?

谢谢!

【问题讨论】:

    标签: php oop class extending


    【解决方案1】:

    同样,这在 PHP 5.3.0 之前是不可能的。

    Late Static Binding 是在 PHP 5.3.0 中引入的,它允许您通过 static 关键字完全按照您的意愿行事。

    class Super {
        protected static $title = 'super';
        public static function get_class_name()        
        {
            echo __CLASS__;
        }
        public static function get_title()
        {
            echo static::$title;
        }
    }
    class Sub extends Super {
        protected static $title = 'sub';
    }
    

    get_class_name() 仍然会返回 Super 尽管 __CLASS__ 总是返回当前类,正在运行的方法被声明(有点像 __FILE__ 无论你是否包含它,它总是返回当前文件)。

    为此,您别无选择,只能在 Sub 类中重新声明函数。

    class Super {
        protected static $title = 'super';
        public static function get_class_name()        
        {
            echo __CLASS__;
        }
        public static function get_title()
        {
            echo static::$title;
        }
    }
    class Sub extends Super {
        protected static $title = 'sub';
    
        public static function get_class_name()        
        {
            echo __CLASS__;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用get_called_class() 来获取您正在调用的类的类名,即使它是静态的。您不必在任何地方声明它。

      来自安德鲁的例子:

      class Super {
          public static function get_class1_name()        
          {
              echo __CLASS__;
          }
          public static function get_title()
          {
              echo get_called_class();
          }
      
      }
      class Sub extends Super {    
          public static function get_class2_name()        
          {
              echo __CLASS__;
          }
      
      }
      Sub::get_title(); // Echos Sub.
      Sub::get_class1_Name(); // echos super
      Sub::get_class2_Name(); // echos sub
      

      因此您不必声明任何变量。

      【讨论】:

      • 从 PHP 5.3.0 开始可用
      • 这个例子没有解决子类和超类之间访问静态属性的区别。
      【解决方案3】:

      幸运的是,我正在为我做一些事情,所以我说,去他妈的,我使用的是 PHP5.3。但即便如此,我不喜欢我必须在每个类中重新声明“get _class _name”,也许我正在扩展 10 个类。所以我想出了这个解决方案:

      class Super {
          protected static $classname = __CLASS__;
          public static function get_classname($name)
          {
              static::$classname = $name;
          }
          public static function get_classname()
          {
              return static::$classname;
          }
      }
      class Sub1 extends Super { }
      class Sub2 extends Super { }
      class Sub3 extends Super { }
      
      $classes = get_declared_classes();
      foreach($classes as $k => $v)
      {
          if (is_subclass_of($v, 'Super'))
          {
              $v::set_classname($v);
          }
      }
      
      echo Sub1::get_classname(); // Sub1
      echo Sub2::get_classname(); // Sub2
      echo Sub3::get_classname(); // Sub3
      

      它可能看起来有点脏,但我不认为它那么糟糕。完成此操作后,您终于可以扩展静态方法而无需重新声明方法。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多