Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要帮助了解php对象的各个方面吗_Php_Class_Object - Fatal编程技术网

需要帮助了解php对象的各个方面吗

需要帮助了解php对象的各个方面吗,php,class,object,Php,Class,Object,我是php新手,需要一些帮助来理解我没有得到的php对象的方面。在类a中,我创建了扩展a的类b和c,但我想做的是从类c访问类a中的public letters变量,以便从类c中获取函数testb() 非常感谢你们的帮助 <?php class a { public $letters; function __construct() { $this->letters->b = new b();

我是php新手,需要一些帮助来理解我没有得到的php对象的方面。在类a中,我创建了扩展a的类b和c,但我想做的是从类c访问类a中的public letters变量,以便从类c中获取函数testb()

非常感谢你们的帮助

   <?php

    class a {
        public $letters;
        function __construct() {
            $this->letters->b = new b();
            $this->letters->c = new c();
        }
    }   

    class b extends a {
        function __construct() {
            echo "hello world from b ";
        }

        private function testb() {
            echo "testing from b";
        }
    }

    class c extends a {
        function __construct() {
            echo "hello world from c ";
            $this->letters->b->testb();
        }
    }


    $a = new a();

?>


下面的脚本与我们的“hello world from b”和“hello world from c”相呼应,但它没有打印“testing from b”…

您不能从类
c
中调用
testb
的原因是
testb
的方法签名将其声明为
private
——这意味着只能在
b
实例中访问它。将可见性更改为默认(无修改器)或
public

例如:

或:

编辑:

问题是您没有从c的构造函数调用超级构造函数-因此,
$this->b的值没有初始化。将c的构造函数更改为:

function __construct() {
    parent::__construct();
    echo "hello world from c ";
    $this->letters->b->testb();
}
不幸的是,这将创建一个无限循环,
a
的构造函数实例化
c
,而
c
的构造函数调用
a
的构造函数。为什么你的字母类甚至可以互相扩展


您还需要在
b
类中更改
testb
的可见性。

好的,如果您从b扩展类c,您可以调用该方法,而不是从类a而不是从c扩展它。

“c”扩展了“a”,并且不继承“b”的方法

你的例子会回来的

致命错误:调用成员函数 非对象上的testb()

为了

$this->letters->b->testb()


在类
a
中,您正在构建类
c
的新对象

这个新对象没有属性
$This->letters->b
,它只有一个未初始化的属性
$This->letters


请注意,新对象从其扩展的类继承属性
$letters
,但不继承实例化的
对象的任何值。因此没有
$this->letters->b
,也没有要调用的函数
$this->letters->b->testb()

PHP对象的一个问题是继承是伪造的(只是有点)。。实例化父对象的子对象时,不会隐式调用父对象的构造函数。相反,您必须显式调用父对象的构造函数

class b extends a {
...
    public __construct() {
        parent::__construct();
        echo("Hello From B!");
    }
...
}
在类
c
构造函数中,
$this->letters
不是对象,并且由于未调用
a
构造函数,因此尚未初始化


如果你只是在玩弄对象,那么忽略这一部分,但是你接近于得到一个循环层次。如果您添加我建议的更改,我相信如果您尝试直接实例化B或C对象,您的代码将爆炸。

不好,我以前尝试过,但它不起作用,这就是我来这里的原因,我只是var_转储了它,它返回空值..:/用我发现的更多问题修改了我的答案。给我一分钟时间运行一个快速测试不好,我以前尝试过,但它不起作用,这就是我来这里的原因,我只是把它甩了,它返回空值..:/你说的没错-父对象的构造函数没有显式调用。然而,为什么它是捏造的?这绝对合乎逻辑。你在扩展一些东西。如果可以选择是否调用父构造函数,为什么要强制调用它?不管怎样,+1来自我,因为你是唯一一个注意到错误的人(其他作者后来明智地编辑了他们的帖子)。继承背后的想法是,如果我有一个B对象扩展了一个a对象,那么B对象也是一个a对象。我能想到的所有其他语言都隐式地执行了这一点。无论如何,这是我的2美分。@watcher父构造函数没有被调用,因为子类定义了一个构造函数,该构造函数与任何其他方法一样替换父构造函数。如果没有B类中的构造函数,当您创建B对象时,会自动调用A类中的构造函数。@jeroen-我想watcher知道这一点@观察者-你不认为那是绝对错误的吗?若父构造函数缺少扩展类所需的功能,但父类中的所有其他函数都完全满足我的要求,那个该怎么办?我被迫调用父构造函数,这样我就可以自由选择是否需要它,这似乎不对吗?如果所有其他语言都是这样实现的(事实并非如此),这并不意味着它是正确的选择,因此我并不真的同意PHP的方式是“捏造的”。它更灵活。@Michael我同意它更灵活,我更多地从假设的角度思考。如果我有一个类车辆和一个扩展车辆的类车辆,那么车辆的构造器应该只做初始化一般车辆应该做的事情。由于汽车是一种交通工具,因此它的构造方式应与任何普通车辆相同,并增加了汽车构造的复杂性。我的观点是,如果不调用超类构造函数,那么继承的整个概念就没有真正被遵循,那么为什么要首先扩展类?如果要覆盖类的所有内容,为什么要扩展类(我说的是c扩展a)
function __construct() {
    parent::__construct();
    echo "hello world from c ";
    $this->letters->b->testb();
}
class b extends a {
...
    public __construct() {
        parent::__construct();
        echo("Hello From B!");
    }
...
}