0

以下を機能させようとしていますが、途方に暮れています...

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 クラスのインスタンスを作成することです。これは を使用して機能し=&ます。しかし、クラス Foo をクラス Bar で拡張すると、子はすべてのデータ属性とメソッドを親クラスから継承すると思いました。ただし、$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 クラスの新しいインスタンスを作成する必要がありますか? または、何か不足していますか?

よろしくお願いします。

4

5 に答える 5

5

子は親クラスからすべてのデータ属性とメソッドを継承していると思いました。

これは本当です。子クラスは親クラスから静的変数と静的メソッドを継承します。さらに、すべての子オブジェクトは、静的およびインスタンスの変数とメソッドを継承します。

既存のクラス構造で必要なものを取得する 1 つの可能性は次のとおりです。

$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 すべてを読んでください。あなたのために。

于 2009-06-12T16:51:14.687 に答える
1

bar には、foo から継承された somethingelse という名前のメンバー変数があります。

オブジェクトとクラスのスコープを混在させています。

説明した効果を本当に達成したい場合は、変数を静的にする必要があるため、そのコンテキストはクラスベースです

于 2009-06-12T16:35:02.510 に答える
0

まず、静的変数とインスタンス変数を区別する必要があります。静的変数はクラスのすべてのインスタンス間で共有されますが、インスタンス変数は共有されません。

Foo と Bar のすべてのインスタンスにまったく同じ SomethingElse-Instance を持たせたい場合は、$somethingelse を静的にする必要があります。

public static $somethingelse

Foo の合成関数を変更する必要があります。

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

この静的フィールドにアクセスするには、次のようにします。 $foo = new Foo(); // 私は Foo $foo->composition(); // 私は別のクラスです Foo:$somethingelse->test(); // 私は、SomethingElse クラスのメソッドです

$bar = 新しいバー(); // 私は Bar で、親は Foo Bar::$somethingelse->test(); // 私は、SomethingElse クラスのメソッドです

Foo と Bar のすべてのインスタンスに独自の SomethingElse インスタンスが必要な場合は、コードを使用できますが、追加する必要があります

$bar->composition()

$bar->somethingelse->test(); の前に

それは

$bar = 新しいバー();

Bar の完全に新しいインスタンスを作成し、そのインスタンスには $somethingelse プロパティがありますが、まだ設定されていません。したがって、composition() を呼び出して設定する必要があります。

すべての Foo と Bar がまったく同じ SomethingElse-instance を持つ必要がある場合は、代わりに静的バージョンを使用する必要があります。これにより、必要なメモリが削減されます。

これがお役に立てば幸いです。それ以外の場合は、さらに説明していただければ幸いです。

于 2009-06-12T17:21:00.327 に答える
0

派生クラスのコンストラクターで親クラスのコンストラクターを呼び出すと、問題は解決すると思います。これは PHP のデフォルトでは発生しないため、データ メンバーの継承に問題がある場合は注意してください。

class Bar extends Foo { パブリック関数 __construct() { 親::__construct();

}

}

于 2009-06-12T20:19:01.240 に答える
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

クラスをあまり抽象的に考えないでください。たとえば、「Royalty」の親クラスである「Person」というクラスがあるとします。

その後、あなたがした場合:

$me = new Person(); $me->firstName = "トーマス"

$princeCharles = 新しいロイヤリティ();

$princeCharles の firstName 属性を "Thomas" に設定したくないでしょうし、$princeCharles->firstName を設定したい場合は、$me の firstName 属性の値を変更しないでください。

$me と $princeCharles の両方に属性「firstName」がありますが、その属性の値は共有していません。

于 2009-06-12T20:05:29.150 に答える