在PHP中,我可以使用多个类来扩展一个类吗?

179
如果我有几个带有所需功能的类,但想要单独进行存储以进行组织,那么我可以扩展一个类来同时具有吗?
class a extends b extends c 编辑:我知道如何逐个扩展类,但我正在寻找一种通过多个基类即时扩展类的方法-据我所知,在PHP中无法实现这一点,但应该有不需要诉诸class c extends bclass b extends a的方法来解决。

2
我正在研究接口,因为我不太喜欢庞大的类层次结构。但是我看不出接口实际上有什么作用? - atomicharri
1
接口使您仅“继承”API,而不是方法体。它强制类a实现来自接口b和c的方法。这意味着如果您想要继承行为,则必须在您的类a中聚合类b和c的成员对象。 - Franck
2
考虑使用装饰器 http://sourcemaking.com/design_patterns/decorator 或策略模式 http://sourcemaking.com/design_patterns/strategy。 - Gordon
如果我认为多重继承是解决问题的最佳方案,我会质疑我的设计。我曾沿着这条路走过,并遇到了这个问题。通常情况下,如果您试图做一些语言自然不支持的事情,您应该质疑您的设计。多重继承似乎过于混乱和笨重。 - Halfstop
3
请将traits视为正确答案。 - Daniel
显示剩余2条评论
18个回答

1

我刚刚用以下方法解决了我的“多重继承”问题:

class Session {
    public $username;
}

class MyServiceResponsetype {
    protected $only_avaliable_in_response;
}

class SessionResponse extends MyServiceResponsetype {
    /** has shared $only_avaliable_in_response */

    public $session;

    public function __construct(Session $session) {
      $this->session = $session;
    }

}

这样我就有能力在扩展了MyServiceResponsetype的SessionResponse内部操纵会话,同时仍然能够独立处理会话。


1
作为一种编程语言,PHP的一个问题是只能进行单一继承,这意味着一个类只能从一个其他类继承。
然而,在许多情况下,从多个类继承会很有益。例如,继承来自几个不同类的方法可以防止代码重复。
这个问题可能导致一个类拥有长时间的继承历史,这通常是没有意义的。
在PHP 5.4中,语言添加了一个称为Traits的新功能。Trait类似于Mixin,它允许您将Trait类混合到现有类中。这意味着您可以减少代码重复并获得好处,同时避免多重继承的问题。 Traits

1

1

如果您想检查一个函数是否是公共的,请查看这个主题:https://dev59.com/J2855IYBdhLWcg3ww3Sa#4160928

并使用call_user_func_array(...)方法来处理多个或没有参数。

像这样:

class B {
    public function method_from_b($s) {
        echo $s;
    }
}

class C {
    public function method_from_c($l, $l1, $l2) {
        echo $l.$l1.$l2;
    }
}

class A extends B {
    private $c;

    public function __construct() {
        $this->c = new C;
    }

    public function __call($method, $args) {
        if (method_exists($this->c, $method)) {
            $reflection = new ReflectionMethod($this->c, $method);
            if (!$reflection->isPublic()) {
                throw new RuntimeException("Call to not public method ".get_class($this)."::$method()");
            }

            return call_user_func_array(array($this->c, $method), $args);
        } else {
            throw new RuntimeException("Call to undefined method ".get_class($this)."::$method()");
        }
    }
}


$a = new A;
$a->method_from_b("abc");
$a->method_from_c("d", "e", "f");

0

一个好的想法是创建一个父类,包含所有函数...即将所有这些功能添加到父类中。

然后将使用这些功能的所有类向下移动。我需要重写那些具体的函数。


0

还没吗?我怀疑他们会不会这么做。现代面向对象编程不鼓励多重继承,因为它可能会变得混乱。 - PhiLho

0

PHP不允许多重继承,但是你可以通过实现多个接口来实现。如果实现过程比较复杂,在单独的类中为每个接口提供骨架实现。然后,你可以通过对象包含将所有接口类委托给这些骨架实现。


-4

class A extends B {}

class B extends C {}

那么A继承了B和C


3
由于这种方法也修改了类B,我们大多数时候希望有两个不相关的类BC(可能来自不同的库),并且同时被A继承,使得A包含从BC获取的所有内容,但是B不包含来自C的任何内容,反之亦然。 - SOFe

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