【问题标题】:Calling a child class function if not exist in parent class如果父类中不存在,则调用子类函数
【发布时间】:2017-04-25 12:49:33
【问题描述】:

我有如下代码---

class CartItem{
    var $v;
    function __construct(){
        $this->f();
    }
    function f(){
         echo 'In parent';
    }
}

class m extends CartItem{
    function f(){
        echo 'In child';
    }
}

new m();

现在在创建 m() 的实例时...它没有任何构造函数,所以它正在调用父类的构造函数。现在里面有一个函数 f 被调用。

我想要的是—— 如果类 m() 定义了函数 f()... 应该调用它而不是父类的函数 f()。

但无论如何它正在调用父类函数,因为它是从父类的构造函数中调用的,而与子类/上下文无关:(

【问题讨论】:

  • 听起来像 xy problem 对我来说
  • protected function f 可以在 CartItem 的构造函数中被调用 m 被实例化。
  • @modsfabio,不是重复的,而是相反的场景
  • @TusharSharma,怎么样?我在找这样的东西

标签: php class


【解决方案1】:

您想在__construct() 中调用一个未在类中定义的方法。这表明CartItem 类是一个抽象概念,并且您不打算实例化它(因为CartItem 的实例可能不包含您项目的足够信息或行为)。

一个抽象概念是使用abstract class 实现的,它尽可能多地定义并定义要在扩展它的具体类中实现的抽象方法。方法f()就是这样一个不能在抽象概念中定义的方法,必须在每个扩展它的类中定义:

abstract class CartItem
{
    public function __construct()
    {
        $this->f();
    }

    abstract protected function f();
}

class m extends CartItem
{
    protected function f()
    {
        // Implement behaviour specific to this class
    }
}

【讨论】:

  • 我刚刚完成了 :) 无论如何谢谢。但是另一个层次的复杂性,我不希望它是抽象的,如果子类定义了它然后获取子类的函数或从父类本身获取它
  • 我不明白你。您可以在基类中定义方法,并在需要时在子类中重新定义。 $this->f() 总是调用正确的实现(子类之一,如果存在,则基类之一)。如果您没有在基类中定义方法f(),那么正确的实现是使其抽象,因为无论如何它都无法实例化。您可以在基类中保留 f() 未定义(而不是使类抽象)并在调用它之前使用 method_exists() 但这是一个 hack。
  • 我已经修改了问题
  • 只是好奇:__construct() 被调用了吗?声明 var $v; 是 PHP 4 语法。 PHP 5 uses the PHP 4 object model when it encounters var 在类声明中。但是 PHP 4 不关心__construct();它不是构造函数,而是 PHP 4 中的常规函数​​。阅读有关 PHP classes and objects 的更多信息并摆脱 var。我希望你没有使用 PHP 4,顺便说一句。
【解决方案2】:

这实际上是一个非常有趣的问题。

所以,据我了解,您是在问(如果这不对,请说):

你可以调用扩展父类的函数吗?

是的,你可以...有点,如果孩子中的方法是静态的。

以这个例子为例(为了简单起见,我没有在构造函数中使用它,但它也可以在那里工作):

class ClassA {

    public function testMeAsWell() {
        return ClassB::testMe();
    }
}

class ClassB extends ClassA {

    static function testMe() {
        return 'do something';
    }
}

$child = new ClassB();
echo $child->testMe();

// outputs 'do something'


$parent = new ClassA();
echo $parent->testMeAsWell();

// also outputs 'do something'

这个工作的原因需要更多的研究,但作为一个猜测,我会说因为 PHP 是编译的,它会在运行时知道这两个类,因此能够弄清楚我们想要它做什么。

因此,进一步说,您想使用变量。是的,你可以,但它们也必须是静态的。

working example

【讨论】:

  • 你已经得到了,正是我想要做的,但如果我定义了那个静态,那意味着我将无法获得任何类属性:(
  • 静态方法只是一个名称很时髦的全局函数。
  • @Alice 如果你不能有一个静态,那么不,你不能这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多