• 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
بیشتر در مورد abstract و final بدونید [ساده و کوتاه]
#1
سلام،
امروز خودم فهمیدم abstract چیکار می کنه وقتی برای یک کلاس نوشته میشه. کار abstract اینه که اگر برای یک کلاس تعریف بشه ، اون کلاس می تونه فقط بعنوان پدر معرفی بشه و میشه دارای فرزند هم باشه. اما تفاوتش با final در اینه که وقتی final برای کلاسی تعریف میشه ، دیگه اون کلاس پدر نمی تونه باشه و فرزندی هم نمیتونه داشته باشه (انگار ازدواج نکرده!) اما فقط میشه از روش شیء ساخت.

دوستان اگر مشکلی در تعریف من هست ، لطفاً راهنمایی کنید تا بیشتر بدونیم و اشتباهامون رو برطرف کنیم. مرسی Heart
دو چیز دیگه ای که الان فهمیدم از abstract اینه که بصورت مستقیم نمی تونی از کلاسی که این کلیدواژه براش تعریف شده استفاده کنی. و بعدی هم اینکه برای توابع تعریف شده در کلاسی که abstract براش تعریف شده هم می تونی از abstract استفاده کنی. به مثال زیر توجه کنید:
کد پی‌اچ‌پی:
abstract class {
abstract public function Echo() {
print 
'Alireza Eskandarpour S.';
}
}
$thing = new A(); #ERROR

class extends {
public function 
Show() {
parent::Echo();
}
}
$thing = new B(); //OKAY 
غایب
  پاسخ
تشکر شده توسط : hosseintdk775
#2
بسم الله الرحمن الرحیم
سلام
نکته ای که هست اینه که وقتی شما متدی رو abstract تعریف میکنی باید همون متد رو در کلاس فرزند هم تعریف کنی
الان این کلاسی که نوشتید ایراد داره / این قسمت رو ببینید:
کد پی‌اچ‌پی:
abstract public function Echo() {
print 
'Alireza Eskandarpour S.';

باید بشه:
کد پی‌اچ‌پی:
abstract public function Echo(); 
در حقیقت وقتی شما باید این متد رو در کلاس فرزند تعریف کنی چه دلیلی داره بیای این متد رو در کلاس اصلی تعریف کنی؟ / وقتی نمی تونی ازش استفاده کنی؟ و اگرم تعریف کنی خطا می گیری (یه تستی بکن)

اینم توضیح خود سایت php:
نقل قول:When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.

در مورد میدان دیدش هم که متدی که در کلاس اصلی هر چی تعریف شده باشه باید در کلاس فرزند هم همون و یا با محدودیت کمتری تعیین بشه / یطبق مثال خودش اگه متدی در کلاس اصلی protected تعریف بشه در کلاس فرزند یا باید protected و یا public باشه

به ترتیب محدودیت کمتر می شه:
private
protected
public

نکته ای هم که هست و متوجه شدم: نمی تونید متدی رو در کلاس هم abstract تعریف کنید و هم private
چون وقتی abstract تعریف می کنیم باید همون رو در کلاس فرزند هم تعریف کنیم که وقتی private اش میکنیم دیگه نمی تونیم بهش دسترسی داشته باشیم و خطا می گیریم
  پاسخ
تشکر شده توسط : cyletech
#3
حسین جان میتونی بیشتر توضیح بدی؟ من هرچی خودم امتحان کردن نفهمیدم و همش یک خطا دریافت می کنم. منظورت از اینکه اگر در کلاس اصلی متدی رو abstract تعریف کنی ، باید اونو در کلاس فرزند هم تعریف کنی چیه؟! اگر اینطوری باشه که اصلاً بدرد نمی خوره متدی رو abstract تعریف کنیم!
غایب
  پاسخ
تشکر شده توسط :
#4
چرا به درد نمی خوره؟ / هر چیزی تو جای خودش نظم بیشتری به برنامه می ده و کاربرد خودش رو داره (البته منم تو این مباحث چندان وارد نیست ها /)

این مثالو نگاه کن:
کد پی‌اچ‌پی:
<?php
abstract class aFamily{
    abstract protected function 
firstName($firstname);// این متد حتما باید در کلاس فرزند تعریف/ساخته/تکمیل/ایجاد بشه
    
protected function lastName(){
        return 
'Baghayi';
    }
}
class 
WhatIsYourName extends aFamily{
    public 
$firstAndLastName = array();
        
    public function 
firstName($firstname) {// چون تو کلاسی که ازش ارث می بریم متدی به این نام ساختارش مشخص شده
// (abstract هم هست) باید تو کلاس فرزند تکمیلش کنی/درستش کنی/بسازیش در غیر اینصورت خطا می گیری
        
$this->firstAndLastName[] = $firstname .' 'parent::lastName();
    }
}

$name = new WhatIsYourName();
$name->firstName('Hossein');
$name->firstName('Ali');
$name->firstName('Vahid');
$name->firstName('Karim');

foreach(
$name->firstAndLastName as $names){
    echo 
'My name is '$names ".\n<br />";
}
?>
کد:
خروجی:
My name is Hossein Baghayi.
My name is Ali Baghayi.
My name is Vahid Baghayi.
My name is Karim Baghayi.

فرض کن یه مهمونی / (دوست پدر) اومده خونه ما / خوب طبیعتا باید نام فامیلی مون رو بدونه (چون پدرمون رو می شناسه) و این پدر هم چند تا بچه داره که فقط اسم اونا رو نمی دونه و اسم اونا رو ازشون می پرسه
اینجا نیاز نیست بگه اسم و شهرتت چیه؟ / فقط اسمشون رو بپرسه کفایت می کنه و ...

تو این کلاس هم دو تا متد تعریف کردیم (کلاس اولی بنام aFamily) / یکی abstract هست که اسم بچه رو (فرضا) می پرسه (که فقط نام متد رو تعریف می کنیم و پارامترهایی که باید داشته باشیم رو و با بدنش کاری نداریم)
و یه متدی هم داریم که نام فامیلی رو توش گذاشتیم که دیگه نیاز نباشه هر دفعه اونم از بچه ها بپرسه (نام فامیلی رو از قبل داریمش) (که اینجا هم بدنه رو ساختیم و تکمیل کردیم)

خوب حالا چون کلاسمون abstract هست ازش (چی می گن؟Smile / ارث می بریم؟ Smile) extend می کنیم و تو کلاس دومی هم می یاییم بدنه متد مون که تو کلاس اولی (abstract) بود رو تکمیل/کامل/می سازیم و از متد دومی هم که (متد معمولی بود) می تونیم ازش استفاده کنیم و مقدارش رو کنار مقداری که اسم بچه ها رو می گیریم قرار می دیم (و در نهایت نام کامل رو خواهیم داشت)

------
در حقیقت ما متد رو در کلاسمون که abstract هست تعریف نمی کنیم / فقط ساختارش رو تعریف می کنیم که این به توسعه دهنده می گه که باید همچین متدی رو با این ساختار تو کلاست (کلاس فرزند) ایجاد کنی و داشته باشیش (یعنی حتما باید بسازیش/درستش کنی/تکمیلش کنی -- در غیر اینصورت خطا می گیری) // (منظورم از ساختار نام متد و پارامتر هاش هست)
---------
اینکه می گی امتحان می کنی و خطا می گیری / چه خطایی می گیری؟
راستی / یه خطایی که تو کدی که تو پست اولی نوشته و بهت نشون داده خواهد شد اینه که برای نام متدت از Echo استفاده کردی
توجه کن که این نام رزرو شده ( رزرو شده دیگه؟SmileBlush ) / چون به این نام تابعی داریم واسه همین خطا می گیری
  پاسخ
تشکر شده توسط : oia cyletech
#5
دیگه اینقدر مباحص خانوادگی رو داخل کلاس نکنید.

abstract در واقع همون تعریف آخر حسین هست. پس ما به کمک abstract یک الگو یا استاندارد برای توسعه کلاس هامون ایجاد میکنیم . از این به بعد هر کلاسی که از کلاس abstract شده به ارث می بره باید طیق قوانین پدر پیاده سازی بشه.



در مورد final هم اشتباه متوجه شدید. کلاس که به صورت final تعریف میشه می تونه از کلاس دیگری به ارث به ببره . اما هییج کلاسی نمی تونه از کلاس final به ارث ببره
  پاسخ
تشکر شده توسط : hosseintdk775 oia cyletech parvane
#6
کلید واژه final : کلید واژه final ( نهایی ) در مواقعی که ارث بری معنی دارد مطرح است. متدی که final هست در کلاس مشتق شده قابل باز تعریف نیست. یعنی شما به کلاس مشتق شده اجازه نمی دید که این متد رو گسترش بده و باید از همون متد کلاس پدر استفاده بشه!
اما در زمانی که یک کلاس final هست به این معنی هست که کل این کلاس قابلیت گسترش ندارد! ( قابل توجه : هدف از ارث بری از یک کلاس گسترش اون کلاس هست ... )

مثال :
# توی این دنیا چند تا کیبرد کامپیوتر هست؟
@ خیلی خیلی خیلی
# چند مدل کیبرد هست؟
@ تقریبا به ازای هر کیبرد می تونه یک مدل کیبرد هم وجود داشته باشه
# نحوه چیدمان کلید ها ( ی استاندارد ) روی تمام کیبرد ها چگونه است؟
@ تقریبا برای همه کیبرد ها یک سان هست!!!
% با اینکه این همه کیبرد توی دنیا هست اما همه یه اونا از یک متد برای پیادهسازی کلید ها استفاده می کنند! اگه فرض کنیم که کلاس کیبرد وجود داره که تمام کلاس کیبرد ها از اون کلاس مشتق شده اند اون وقط باید بگیم در کلاس پایه متدی وجود داره که اصطلاحآ final هست و همه کلاس های پایه بدون اینکه این متد رو گسترش بدن از اون استفاده می کنن! وظیفه این متد ساخت کلید های استاندارد در کیبرد هست!!!

کلید واژه abstract : شاید اگه با interface هم اشنا بشید بهتر موضوع abstract درک بشه! ( جدای از فامیل بازی Wink )
ایجاد یک الگو برای کلاس ها مشتق شده ! که فقط در کلاس پایه الگو تعریف و در کلاس مشتق شده الگو باید پیاده بشه!

مثال: فرض کنید که کلاس پایه ایی دارید به اسم موجود زنده که در اون یک متد بصورت انتزاعی تعریف شده به نام تنفس که لازمه هر موجود زنده هست! حالا ببنید که این متد در کلاس آبزیان، در کلاس جانوران و در کلاس حشرات هرکدام به یک گونه متفاوت پیاده شده است!
  پاسخ
تشکر شده توسط : hosseintdk775 zoghal cyletech parvane
#7
نقل قول:راستی / یه خطایی که تو کدی که تو پست اولی نوشته و بهت نشون داده خواهد شد اینه که برای نام متدت از Echo استفاده کردی
آره متوجه این موضوع شدم ولی با خودم قبل از اینکه کد رو تست کنم فکر می کردم که PHP به بزرگ و کوچک بودن حروف حساسه (هست دیگه!) ولی نمیدونم چرا به این یکی گیر داده! Echo حتماً با echo باید فرق داشته باشه. انگار نداشته ولی که من خطا گرفتم Heart
راستی قربون مثالت Angel کامل فهمیدم جریان چیه. ولی باید یکبار برای خودم اتفاق بیافته تا بیشتر درکش کنم. Tongue

نقل قول:در مورد final هم اشتباه متوجه شدید. کلاس که به صورت final تعریف میشه می تونه از کلاس دیگری به ارث به ببره . اما هییج کلاسی نمی تونه از کلاس final به ارث ببره
خب منم منظورم همین بود دیگه! من گفتم:
نقل قول:اما تفاوتش با final در اینه که وقتی final برای کلاسی تعریف میشه ، دیگه اون کلاس پدر نمی تونه باشه و فرزندی هم نمیتونه داشته باشه
یعنی اون کلاسی که final شده فرزند نمیتونه داشته باشه و چون نمیتونه داشته باشه پس پدرم نیست اما نگفتم که خودش می تونه از کلاس دیگری ارث بری کنه. باور کن میدونستم Big Grin
محمد امین به زبان شیرین فارسی بیشتر در مورد interface هم توضیح میدین. plz? Heart
غایب
  پاسخ
تشکر شده توسط : hosseintdk775


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان