سؤال

أحاول الحصول على ما يلي للعمل، لكنني في خسارة ...

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

ما أود القيام به هو إنشاء مثيل من فئة شيء ما داخل الفئة فو. هذا يعمل باستخدام =&. وبعد لكن عندما أقوم بتوسيع الفئة فو مع شريط فئة، اعتقدت أن الطفل يرث جميع سمات البيانات والأساليب من الطبقة الأصل. ومع ذلك، يبدو ذلك $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 = 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 جديد بالنسبة لك.

نصائح أخرى

يحتوي Bar على متغير عضو يدعى شيء ما، والتي ورثت من فو.

أنت خلط كائن ونطاق الفصل.

إذا كنت ترغب حقا في تحقيق التأثير الموصوف، فعليك أن تجعل الثابت المتغير الخاص بك، لذلك سياقه مقره

أولا، عليك التمييز بين المتغيرات المثلية. يتم مشاركة المتغيرات الثابتة بين جميع مثيلات فئة، ومتغيرات المثيل ليست كذلك.

إذا كنت ترغب في الحصول على كل مثيل من FOO و BAR أن يكون لديك نفس مثيل PhotoLse الخاص بالضبط، فعليك إجراء ثابت $

ثابت الثابت $

ويجب عليك تغيير وظيفة تكوين FOO:

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

للوصول إلى هذا الحقل الثابت يمكنك القيام بما يلي: $ foo = foo new ()؛ // أنا فو $ foo-> تكوين ()؛ // أنا بعض فصول أخرى فو: $ شيء شيء-> اختبار ()؛ // أنا طريقة في فئة شيء ما

$ بار = شريط جديد ()؛ // أنا بار، والدي هو foo bar :: $ photosealse-> اختبار ()؛ // أنا طريقة في فئة شيء ما

إذا كنت ترغب في كل مثيل FOO و BAR لها مثيل خاص بهم، فيمكنك استخدام التعليمات البرمجية الخاصة بك، ولكن عليك إضافة

$ Bar-> تكوين ()

قبل شريط $-> شيء ما-> اختبار ()؛

هذا بسبب

$ بار = شريط جديد ()؛

قمت بإنشاء مثيل جديد تماما من البار ولهذا المثيل يحتوي على خاصية $ Portselse، لكن لم يتم تعيينه بعد. لذلك تحتاج إلى استدعاء التكوين () لتعيينه.

إذا كان يجب أن يكون لكل FOO و BAR نفس مثيل شيء PhotoLse، يجب عليك استخدام الإصدار الثابت بدلا من ذلك، لأنه يقلل من الذاكرة اللازمة.

آمل أن يكون هذا يمكن أن يساعدك. وإلا فإنني سعيد جدا لشرح ذلك.

قائلا أن سمات سهم الفصول لا تعني حصة الكائنات قيم السمة.

كما لاحظ الآخرون، فأنت مربكة الطبقات مع الحالات.

ملاحظة، ستحصل على نفس الخطأ إذا فعلت:

$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

فكر في الطبقات أقل تجريدا. على سبيل المثال، قد يكون لديك فئة "شخص"، وهو فئة الوالدين من "الملوك".

ثم إذا فعلت:

$ أنا = شخص جديد ()؛ $ me-> الاسم الأول = "توماس"

$ prilecharles = الملوكيات الجديدة ()؛

لن ترغب في أن يكون لدى PrinceCarles $ من سمة الاسم الأول تساوي "Thomas"، وإذا كنت ترغب في تعيين $ $ prilecharles-> اسم المستخدم أولا، فأنت لا تفعل ذلك لتغيير قيمة سمة الاسم الأول لي.

كلا من $ لي و $ برينشاراتلز لها سمة "الاسم الأول"، لكننا لا نشارك القيمة من تلك السمة.

أعتقد أن مشكلتك سيتم حلها إذا كان في منشئ الطبقة المشتقة سيتصل منشئ الطبقة الأصل. لا يحدث هذا بشكل افتراضي في PHP، لذا احتفظ به في الاعتبار عندما يكون لديك مشكلات مع ورث أعضاء البيانات.

يطيل شريط الفئة فو {الوظيفة العامة __constrond () {الوالد :: __ بناء ()؛

}

}

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top