需要帮助了解php对象的各个方面吗
我是php新手,需要一些帮助来理解我没有得到的php对象的方面。在类a中,我创建了扩展a的类b和c,但我想做的是从类c访问类a中的public letters变量,以便从类c中获取函数testb() 非常感谢你们的帮助需要帮助了解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
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!");
}
...
}