محمدجوکار
1 سال پیش توسط محمدجوکار مطرح شد
4 پاسخ

محدودیت و یا شاید باگ در php Inheritance

سلام دوستان. امروز یه اتفاق جالب برام افتاد که نمیدونستم چطور باید هندلش کنم. کلی وقت گذاشتم تا به نتیجه‌ی زیر رسیدم ولی هنوز هم علت این موضوع برای من روشن نشده...
بعد از کلی آزمون و خطا، مطالب زیر رو به عنوان یک نکته آموزشی در یک انجمن قرار دادم. دیگه ادیت نمیکنم و همونو همینجا کپی میکنم. ممنون میشم چک کنید و لاجیکی که پشت این موضوع هستو برای من توضیح بدید. با تشکر.
متن:
مشکل زیر، فقط بحث یک مورد استثنا رو بیان میکنه و به این معنی نیست که باید به این روش کد زد، فقط به نظرم دونستنش جالبه. و به این خاطر بهش میگم استثنا، چون روی حرفم هستم که حس میکنم این یا یک نقص در php هست یا منطقی درش وجود داره که هنوز من ازش اطلاعی کسب نکردم.

راه حل درست هم، با استفاده از overriding یا Late Static Binding میتونه هندل بشه.

:

class A {
    private function foo() {
        echo 'hello parent' ;
    }

    public function test() {
        $this->foo();
    }

}

class B extends A {
    private function foo() {
        echo 'hello child' ;
    }

}

$b = new B();
$b->test();

در صورتی که بخوایم در مثال بالا از ارث بری استفاده بکنیم:

وقتی متد test صدا زده میشه، و درون متد test هم گفتیم که برو و متد foo رو برگردون، ابتدا مفسر میاد میبینه که اصلا متد foo وجود داره یا خیر.

اگر کلا، نه در کلاس child و نه در کلاس parent، این متد وجود نداشته باشه، خب قطعا میگه همچین چیزی وجود نداره یا اصلا چیزی بر نمیگردونه.

حالا اگر متد foo درون کلاس پدر وجود داشته باشه و خصوصی هم باشه (مثل کلاس A در کدهای بالا) ، اتفاقات زیر میافته:

یک/ متد foo درون کلاس child وجود داره، که دو حالت به وجود میاد:

حالت اول: متد foo پابلیک باشه = محتویاتشو برمیگردونه.

حالت دوم: متد foo پابلیک نباشه = اگر متد foo هر چیزی به جز پابلیک باشه اونو برنمیگردونه و اینجا یه حالت استثنا به وجود میاد. که میره و متد foo پرایوت پدرش رو برمیگردونه.

دو/ متد foo درون کلاس child وجود نداره:

در این صورت، مجددا متد foo پدر برگردونه میشه
ـــــــــــــــــــــــــــــــــــــــــــــــــــــــ
و حالا سوال من:‌

کدهای زیر رو در نظر بگیرید:

class A {
    private function foo() {
        echo 'hello parent' ;
    }

    public function test() {
        $this->foo();
    }

}

class B extends A {

}

$b = new B();
$b->test();

چرا در اینجا با توجه به این که خود کلاس child متد foo نداره، و ما داریم توسط متد test، متدی رو صدا میزنیم که وجود خارجی نداره، به ارور بر نمیخوریم و در نهایت تعجب، میره و محتویات متد foo پدرش رو برمیگردونه؟؟؟
با این حال که سطح دسترسیش private هست!!


ثبت پرسش جدید
علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 1 سال پیش مطرح شد
1

این موضوع کاملا منطقی هست

کلاسی داری به نام B که از A ارث بری میکنه...
وقتی متد test رو اجرا میکنی و درون کلاس B همچین متدی وجود نداره، مفسر میره سراغ کلاس پدر و اونجا test رو پیدا میکنه. بعد داخل test رفرنسی هست به متد foo که در اون مرحله با وجودی که private هست اما داره از داخل خود اون کلاس کال میشه.


محمدجوکار
تخصص : دانشجوی برنامه‌نویسی
@mamadyaqa 1 سال پیش مطرح شد
0

@ali.bayat
ممنونم از پاسخگویی شما
در آخرین کدهایی که گذاشتم، من اینطوری فکر میکردم که با توجه به مسئله‌ی ارث بری، کلاس B صرفا متد test رو از کلاس A به ارث میبره و دیگه به متد foo که در کلاس پدر وجود داره،‌ اهمیتی نمیده. اما انگار اینطوری نیست.

وقتی ارث بری صورت میگیره، من منطقا این دوتا کد زیر رو با هم یکی میدونم. آیا واقعا اینها با همدیگه یکی نیستن؟؟؟؟؟؟

class A {
    private function foo() {
        echo 'hello parent' ;
    }

    public function test() {
        $this->foo();
    }

}

class B {
    private function foo() {
        echo 'hello child' ;
    }
    public function test() {
        $this->foo();
    }
}
class A {
    private function foo() {
        echo 'hello parent' ;
    }

    public function test() {
        $this->foo();
    }

}

class B extends A {
    private function foo() {
        echo 'hello child' ;
    }
}

علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 1 سال پیش مطرح شد
1

وقتی خروجی یکسان نیست، چطور میتونن یکسان باشند؟

به بلوک کد دوم دقت کن:
وقتی B از A ارث بری میکنه.. یعنی مولفه های A در B موجود هستند..
در ادامه متد foo داره override میشه.. ولی تاثیری نداره
چونکه متد test در کلاس A موجوده و به واسطه اشاره‌گر this داره به متد foo در داخل خود کلاس A اشاره میکنه..


محمدجوکار
تخصص : دانشجوی برنامه‌نویسی
@mamadyaqa 1 سال پیش مطرح شد
0

@ali.bayat
متشکرم از وقتی که گذاشتید


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام