2009-06-12 68 views
0

我试图让下面的工作,但我不知所措......PHP5类:继承一个组合类吗?

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'; 
    } 
}

我希望做的是创造SomethingElse的一个实例班级内的班级。这可以使用=&。但是当我用class Bar扩展Foo类时,我认为子继承了父类的所有数据属性和方法。然而,似乎$this->somethingelse不子类酒吧工作:

$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的新实例吗?或者我错过了什么?

在此先感谢您的帮助。

+1

你继承了Foo类,创建类Foo,这somethingelse设置的不是实例。 – cloudhead 2009-06-12 16:33:45

回答

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

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

你是混合对象和类作用域。

如果你真的想达到的效果所描述的,你必须让你的静态变量,所以它的上下文类基于

0

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

如果你想Foo和Bar的每个实例有完全相同的SomethingElse,比如你必须做出$ somethingelse静:

公共静态$ somethingelse

,你应该改变构图功能富:

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

要访问此静态字段,你可以做到以下几点: $富=新的Foo(); //我是Foo $ foo-> composition(); //我是其他班级 Foo:$ somethingelse-> test(); //我是SomethingElse类中的一个方法

$ bar = new Bar(); //我是Bar,我的父母是Foo Bar :: $ somethingelse-> test(); //我在SomethingElse类

的方法。如果你想Foo和酒吧的每一个实例都有自己的SomethingElse例如,您可以使用您的代码,但是你需要添加

$酒吧,>组成()在$ bar-> somethingelse-> test();之前加上

;

这是因为用

$ bar = new Bar();

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

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

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

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',但我们不共享该属性的

0

我认为你的问题将得到解决,如果在派生类构造函数将调用父类的构造函数。这在PHP中默认情况下不会发生,因此当您在继承数据成员时遇到问题时请记住它。父级:: __构造();公共函数__构造(){ 父级:: __构造();

} 

}