PHP调用父类方法

3

我不确定是否有这样一个术语,但我想做的是:

class A {
    function a($a) {
        return $a;
    }
}

class B extends A {
    function a($a) {
        return parent::a('B' . $a);
    }
}

class C extends B {
    function a($a) {
        return superparent::a('C' . $a);
    }
}

$c = new C();
echo $c->a('C'); // "CC"

我想绕过所有媒体类并在父级上调用函数,这个函数是第一次定义的地方 - 这可能吗?

2
这感觉像是代码异味。类C不应该知道类A的任何信息,甚至不应该知道它的存在。如果它们在执行不同的任务,你应该使用不同的方法。 - M. Eriksson
4个回答

9
不,这是个糟糕的想法。所有类 C 都知道它继承了 B,但它不能知道也不应该知道 B 继承了什么,如果确实继承了些什么。 C 不能指望 B 继承任何东西,也不应该知道那个祖先类的具体方法及其实现细节。如果建立此类三重依赖关系,代码将开始出现各种问题,明天你可能会重构 B 来继承另一个类,或者干脆不继承任何类。
类只应与直接相关的同级交互,无论是通过继承还是依赖注入。
从逻辑上讲:B 添加了 一些必要的行为使 A 成为 "一个 B",C 添加了一些内容使其成为一个 CCB 的基础上构建,所以任何 B 做的事情 C 也应该做。将 C "跳过" B 回到 A 表明您的逻辑和职责分配在类层次结构中混淆了。

3

尽管有任何工程软件的投诉(你试图做的事情必须通过其他方法实现),我认为我的两个例子都应该能够正常工作:

使用trait:

<?php

trait Bypass_trait {
    public function super_ref() {
        return parent::super_ref();
    }
}

class A {
    function a($a) {
        return $a;
    }

    function super_ref() {
      return $this;
    }
}

class B extends A {
    use Bypass_trait;

    function a($a) {
        return $this->super_ref()->a('B' . $a);
    }
}

class C extends B {
    use Bypass_trait;

    function a($a) {
        return $this->super_ref()->a('C' . $a);
    }
}

$c = new C();
echo $c->a('C'); // "CC"

使用接口:

<?php

interface Bypass {
  public function super_ref();
}

class A implements Bypass {
    function a($a) {
        return $a;
    }

    function super_ref() {
      return $this;
    }
}

class B extends A implements Bypass {
    function a($a) {
        return $this->super_ref()->a('B' . $a);
    }

    function super_ref() {
      return parent::super_ref();
    }
}

class C extends B implements Bypass {
    function a($a) {
        return $this->super_ref()->a('C' . $a);
    }

    function super_ref() {
      return parent::super_ref();
    }
}

$c = new C();
echo $c->a('C'); // "CC"

-1

我认为你可以将“A”作为抽象类,然后让B和C来覆盖它。


这是一种可能的解决方案来规划类,但几乎没有回答问题。 - deceze

-1

你可以选择调用哪个父类方法,例如 A::a('C' . $a)

当像这样调用父类函数时,它不会静态调用,就像 parent::a() 一样。


3
不,它并不是静态调用,就像 parent::a() 一样。您可以尝试在类A中声明的函数内使用 $this 进行调用。 - Noémi Salaün
3
虽然从技术上讲这一切都是正确的,但实际上这仍然是一个可怕的行为。 - deceze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接