PHP5类:继承一个组合类?

时间:2009-06-12 16:28:32

标签: php inheritance composition

我正在努力让以下工作,但我不知所措......

class Foo {
    public $somethingelse;

    function __construct() {
        echo 'I am Foo';
    }
    function composition() {
        $this->somethingelse =& new SomethingElse();
    }
}
class Bar extends Foo {
    function __construct() {
        echo 'I am Bar, my parent is Foo';
    }
}
class SomethingElse {
    function __construct() {
        echo 'I am some other class';
    }
    function test() {
        echo 'I am a method in the SomethingElse class';
    }
}

我想要做的是在类Foo中创建SomethingElse类的实例。这可以使用=&。但是当我用类Bar扩展类Foo时,我认为子类继承了父类的所有数据属性和方法。但是,似乎$this->somethingelse在子类Bar中不起作用:

$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class

$bar = new Bar(); // I am Bar, my parent is Foo
$bar->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object

那么,以这种方式继承是不可能的?如果我想在那里使用它,我应该从类Bar中创建一个类SomethingElse的新实例吗?或者我错过了什么?

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:5)

  

我认为孩子继承了父类的所有数据属性和方法。

这是真的 - 子类从父类继承静态变量和静态方法。此外,任何子对象都将继承静态和实例变量和方法。

使用现有的类结构获得所需内容的一种可能性是:

$bar = new Bar();
$bar->composition();// here you are calling the parent method, sets instance var $somethineelse
$bar->somethingelse->test();// now you can call methods

在子实例中完成继承变量(在本例中为对象)的另一种方法是这样的:

class Foo {
    protected $somethingelse;
    public function __construct() {
        $this->somethingelse = new SomethingElse();
    }
}

class Bar extends Foo {
    public function __construct() {
        parent::__construct();
        // now i've got $somethingelse
    }
 }

有关PHP 5中类和对象的非常好的概述,请看一下: http://php.net/manual/en/language.oop5.php 请务必阅读所有内容,如果OO对您而言可能需要几次。

答案 1 :(得分:1)

bar有一个名为somethingelse的成员变量,它继承自foo。

你正在混合对象和类范围。

如果你真的想要实现所描述的效果,你必须使你的变量变为静态,所以它的上下文是基于类的

答案 2 :(得分:0)

首先,您必须区分静态变量和实例变量。静态变量在类的所有实例之间共享,实例变量不是。

如果你希望Foo和Bar的每个实例都具有完全相同的SomethingElse-Instance,你必须使$ somethingelse静态:

public static $ somethingelse

你应该改变Foo的作文功能:

function composition() {
    self::$somethingelse = new SomethingElse();
}

要访问此静态字段,您可以执行以下操作: $ foo = new Foo(); //我是Foo $ foo->组合物(); //我是其他班级 FOO:$ somethingelse->测试(); //我是SomethingElse类中的一个方法

$ bar = new Bar(); //我是Bar,我的父母是Foo 酒吧:: $ somethingelse->测试(); //我是SomethingElse类中的一个方法

如果您希望Foo和Bar的每个实例都有自己的SomethingElse实例,您可以使用您的代码,但是您需要添加

$酒吧,>组合物()

在$ bar-> somethingelse-> test();

之前

那是因为

$ bar = new Bar();

您创建了一个全新的Bar实例,该实例具有$ somethingelse属性,但尚未设置。所以你需要调用composition()来设置它。

如果每个Foo和Bar应该具有完全相同的SomethingElse-instance,则应该使用静态版本,因为它减少了所需的内存。

我希望这可以帮到你。否则我很乐意进一步解释。

答案 3 :(得分:0)

说类共享属性并不意味着对象共享属性值

正如其他人所指出的那样,你会把类与实例混淆。

注意,如果你这样做,你会得到同样的错误:

$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class

$foo2 = new Foo(); // I another Foo
$foo2->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object

不那么抽象地考虑这些类。例如,您可能有一个类“Person”,它是“Royalty。”的父类。

然后,如果你做了:

$ me = new Person();    $ me-> firstName =“Thomas”

$ princeCharles = new Royalty();

你不希望$ princeCharles的firstName属性等于“Thomas”,如果你想设置$ princeCharles-> firstName,你不要改变$ firstName属性的值。我

$ me和$ princeCharles都有一个属性'firstName',但我们不共享该属性的

答案 4 :(得分:0)

我认为如果在派生类构造函数中调用父类构造函数,您的问题将得到解决。默认情况下,这在PHP中不会发生,因此在遇到继承数据成员的问题时请记住这一点。

类Bar延伸Foo {     public function __construct(){         父:: __构建体();

}

}