在PHP中从父类访问扩展类

在PHP中从父类访问扩展类,php,class,oop,extend,Php,Class,Oop,Extend,我有两个类,类A和类B,我试图通过类A中的函数访问类B 目前,我可以通过在类a的函数中创建一个新的类B实例来实现这一点,但我想知道是否有一种方法可以做到这一点,而不必在类a中创建一个新的类B实例 下面是我想做的一个例子: class a{ function a(){ return $this->b(); } } class b extends a{ function b(){ return "It Works!";

我有两个类,类A和类B,我试图通过类A中的函数访问类B

目前,我可以通过在类a的函数中创建一个新的类B实例来实现这一点,但我想知道是否有一种方法可以做到这一点,而不必在类a中创建一个新的类B实例

下面是我想做的一个例子:

class a{

    function a(){
        return $this->b();
    }


}

class b extends a{

    function b(){
        return "It Works!";
    }

}

$doIt = new a();
echo $doIt->a();

你不能。但是你可以期待一个抽象的方法

abstract class a {
    function a() {
        return $this->b(); // OK
    }
    abstract function b(); // Has no method body. Classes extending this class will implement it
}
class b extends a {
    function b() {
        return 'something';
    }
}
$doIt = new b(); // Cannot instantiate abstract class a
echo $doIt->a();
根据您的评论:


基本上,我有B类与数据库一起工作,A类将用户在站点上的操作连接到B类。所以用户做一些事情->A类开始工作->将信息传递到B类以添加到数据库中。这似乎不太可能,但我知道有些人比我有更多的知识,所以我想看看是否有其他人知道这样做的方法

正如您所描述的:B使用数据库,A执行用户请求的操作。B听起来像是某种映射器/数据访问对象,而A听起来像是一种服务,我将更仔细地参考BMapper和AService

您概述的内容表明您没有正确使用PHP继承。继承代表的是一种关系。图像是媒体,PathMover是动画师,等等。。。。虽然@Malcolm的答案在技术上是可行的,但它并不适用于您的场景

在OOP中,我们可以说BMapper是一个服务的依赖项。因此,每当我们在AService中调用一个方法时,我们都希望它依赖于BMapper的一个实例。此关系通常通过依赖项注入来满足,请参见:


您可以看到,我们已经在其构造函数中定义了依赖类的依赖关系,以满足使用该类的任何人/任何人的需求。

它不是这样工作的。您不能实例化A和访问方法B。您可以实例化A中的B和访问方法。因此,从A实例化B是唯一的选项?为什么要尝试这样做?你的目标是什么?也许我们可以提出一个更好的方法来实现它?你所建议的方式似乎打破了oop模型。A不知道B,但B知道A。你可以使用A,但它对B一无所知。基本上我有B类,可以处理数据库,以及将用户在站点上的操作连接到类B的类A。因此,用户执行某些操作->类A开始工作->将信息传递给类B以添加到数据库中。看起来这并不是所有的可能,但我知道有很多人比我有更多的知识,所以我想知道是否有人知道如何做这件事。这相当于C++的虚拟函数吗?不,它相当于C++纯虚函数。除非用FED进行修饰,否则所有函数默认等于C++虚拟函数。抓住你了。很酷。很高兴知道所有的php方法都是作为虚拟函数使用的。我们投票支持显示对象组合是一种方式。
<?php

class AService {

    private $bMapper;

    public function __construct(BMapper $bMapper)
    {
        $this->bMapper = $bMapper;
    }

    public function doAction()
    {
        return $this->bMapper->performSomethingInDatabase();
    }

}

class BMapper {

    public function performSomethingInDatabase()
    {
        /**
         * ..whatever
         */
    }

}

$service = new AService(new BMapper);
$service->doAction();