مفاهیم public ،private و protected

30 فروردین 1399
درسنامه درس 3 از سری شی گرایی در PHP
php-oop-private-public-protected

با قسمت سوم از سری آموزشی برنامه نویسی شیء گرای PHP در آکادمی روکسو در خدمت شما هستیم. در این قسمت قصد داریم تا به ادامه‌ی مباحث گذشته پرداخته و کاربرد مباحث قبلی را به شما نشان دهیم. اگر با مباحث اولیه آشنا نیستید می توانید قسمت های قبلی این سری را مطالعه کنید.

قبل از رفتن به سراغ مباحث قبلی باید نکته ای کوچک را برایتان توضیح دهیم. این نکته در رابطه با اپراتور Scope Resolution است. گرچه استفاده از این اپراتور آنچنان شایع نیست اما برای اینکه شما با این مبحث کاملا غریبه نباشید یک مثال از آن ارائه میدهیم تا درکی کلی از آن پیدا کنید.

اپراتور Scope Resolution (::) چیست؟

این اپراتور در زبان PHP به نام «Paamayim Nekudotayim» هم خوانده می شود که در زبان عبری به معنی «دو تا دونقطه» می باشد. اگر برای شما سوال ایجاد شده است که چرا اسمی عبری برای این اپراتور انتخاب شده است باید بگوییم این نام در Zend Engine توسعه داده شده و برای اسرائیل در نسخه ی 3 PHP وجود داشت و با گذشت زمان همچنان باقی ماند.

این اپراتور به شما اجازه ی دسترسی به متدها، خصوصیاتِ static یا constant و یا overridden در یک کلاس را میدهد.

 اگر از قسمت قبل یادتان باشد نام انگلیسی خصوصیات properties و نام متدها methods بود.

constant (ثابت) ها در یک کلاس چه هستند؟

  • ثابت ها در واقع وجود های ثابتی در یک کلاس هستند.
  • این ثابت ها دیگر مانند متغیر ها دارای علامت دلار قبل از اسمشان نیستند.
  • برای دسترسی به این ثابت ها می توانید از قاعده ی $classname :: constant استفاده کنید. در این قاعده classname می تواند یک متغیر نیز باشد.

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

<?php
  class MyClass
  {
  const constant1 = 'PHP Class Constant';
  function PrintConstant() 
  {
  echo  self::constant1 . "<br>";
  }
  }
  echo MyClass::constant1 . "<br>";
  $classname = "MyClass";
  echo $classname::constant1 . "<br>"; // As of PHP 5.3.0
  $class = new MyClass();
  $class->PrintConstant();
  echo $class::constant1."<br>"; // As of PHP 5.3.0
 ?>

مفهوم خصوصیات public ،private و protected

همانطور که قبلا گفتیم خصوصیات (properties) میتوانند یکی از سه حالت public ،private و protected را داشته باشند. همچنین گفتیم که public به معنای دسترسی از همه جا، private به معنی دسترسی تنها از طریق کلاسِ سازنده ی عضو و protected به معنای دسترسی تنها در درون خودِ کلاس یا با رابطه ی وراثت بین کلاس ها (کلاس های فرزند و پدر) است.

تا اینجا بحث تنها تئوری بود اما میخواهیم در قالب مثالی تفاوت این سه حالت را برای شما توضیح دهیم:

<?php
// مرحله 1
class Myclass
{
 // مرحله 2
 public $font_size ="18px"; 
 // مرحله 3
 private $font_color = "blue"; 
 // مرحله 4
 protected $string_name = "RoxoAcademy"; 
 // مرحله 5
 function property_print()
 {
 echo $this->font_size;
 echo $this->font_color;
 echo $this->string_name;
 }
}
$obj = new MyClass;
echo $obj->font_size; //نتیجه 1 
echo $obj->font_color; //نتیجه 2
echo $obj->string_name; //نتیجه 3
$obj->property_print(); //نتیجه 4
?>

اگر با دقت به مثال بالا نگاه کنید متوجه می شوید برای هر قسمت، یک مرحله / نتیجه تعریف کرده ایم. مراحل، بر اساس شماره، به شرح زیر هستند:

مرحله 1: ساخت یک کلاس (اگر آشنایی ندارید به قسمت دوم این سری مراجعه کنید)

مرحله 2: ثبت font_size$ به عنوان یک خصوصیت public

مرحله 3: ثبت font_color$ به عنوان یک خصوصیت private

مرحله 4: ثبت string_name$ به عنوان یک خصوصیت protected

مرحله 5: ساخت یک متد برای نمایشِ مقادیرِ این ویژگی ها. اگر از قسمت های قبل یادتان باشد، در این مرحله، از آنجایی که از هیچ کلید واژه ای (public ،private و protected) در هنگام تعریف متد استفاده نکردیم، متد ما به صورت اتوماتیک حکم public میگیرد.

حالا نوبت به بررسی نتایج میرسد. ممکن است در ذهن شما سوال پیش آمده باشد که چرا چنین کاری کردیم؟ پاسخ ساده است. با این کار به راحتی می توانید با تفاوت مفاهیم public ،private و protected آشنا شوید و این تفاوت ها را در عمل ببینید، نه فقط روی کاغذ. اما نتایج:

نتیجه 1: خروجیِ این دستور عبارت «18px» خواهد بود.

نتیجه 2: خروجی این دستور یک خطا خواهد بود. متن خطا به این شکل نمایش داده خواهد شد:

Fatal error: Cannot access private property Myclass::$font_color in F:\wamp\..

این خطا به شما می گوید که نمیتوانید به یک خصوصیت private دسترسی داشته باشید.

اگر کنجکاو هستید باید بگویم عبارت «F:\wamp\..» که در ادامه ی خطا آمده است از آن جهت بوده که ما نرم افزار WAMP را روی سیستم خود نصب داشته ایم و دستورات PHP را روی آن اجرا کرده ایم. اگر روی یک وب سرور واقعی باشید ممکن است این متن متفاوت باشد که البته اهمیت چندانی ندارد (محض اطلاع شما گفته شد).

نتیجه 3: نتیجه ی این دستور نیز یک خطاست. متن خطا به صورت زیر خواهد بود:

Fatal error: Cannot access protected property Myclass::$string_name in F:\wamp\..

این خطا هم مانند مورد قبلی به شما می گوید نمیتوانید به خصوصیت protected دسترسی داشته باشید.

نتیجه 4: نتیجه ی این دستور عبارت «18pxblueRoxoAcademy» خواهد بود. چرا؟ به این خاطر که هنگام تعریف این متد (()property_print) ذکر کردیم که مقادیر مورد نظر را پشت سر هم نمایش دهد و بین آنها فاصله ای نگذارد. توجه داشته باشید که زدن کلید اینتر و رفتن به خط بعدی در سورس کد شما هیچ تاثیری روی نمایش آن ندارد. به همین خاطر است که میتوانیم سورس کد را minify کنیم.

مفهوم متدهای public ،private و protected

تمام گفته های سه حالت برای خصوصیات برای متدها نیز قابل اطلاق است؛ یعنی public به معنای دسترسی از همه جا، private به معنی دسترسی تنها از طریق کلاسِ سازنده ی عضو و protected به معنای دسترسی تنها در درون خودِ کلاس یا با رابطه ی وراثت بین کلاس ها (کلاس های فرزند و پدر) است.

حالا جهت روشن شدن کامل این تفاوت ها، به مثال زیر دقت کنید.

<?php
// مرحله 1
class Myclass
 {
 // مرحله 2
 public function my_public_method()
 {
 echo "This is a Public method"; 
 } 
 private function my_private_method()
 {
 echo "This is a Private method"; 
 }
 protected function my_protected_method()
 {
 echo "This is a Protected method"; 
 } 
 // نکته
 function test()
 {
 $this->my_public_method();
 $this->my_private_method();
 $this->my_protected_method();
 }
 }
 $obj = new MyClass;
 $obj->my_public_method(); //نتیجه 1
 $obj->my_private_method();//نتیجه 2
 $obj>my_protected_method();//نتیجه 3
 $obj->test(); //نتیجه 4
?>

در این مثال هم مراحل به شرح زیر است:

مرحله 1: ساخت یک کلاس

مرحله 2: ساختن متدهای public ،private و protected.

نکته: برای متد ()test از هیچ کلمه ی کلیدی استفاده نکردیم، بنابراین به طور پیش فرض public خواهد بود.

نتیجه 1: نتیجه ی این دستور، نمایش عبارت «This is a public method» خواهد بود.

نتیجه 2: نتیجه ی این دستور یک خطا خواهد بود. متن خطا از قرار زیر است:

Fatal error: Call to private method Myclass::my_private_method() from context '' in F:\wamp\www..

این خطا به شما می گوید که نمیتوانید یک متد private را از کلاسِ Myclass صدا بزنید. به عبارت دیگر نمی شود یک نمونه از کلاسی را بسازید و با آن یک متد private را صدا بزنید. چنانچه نمیدانید نمونه چیست به قسمت قبلی (قسمت دوم) مراجعه کنید.

نتیجه 3: نتیجه ی این دستور یک خطا خواهد بود. متن خطا از قرار زیر است:

PHP Fatal error:  Uncaught Error: Call to protected method

این خطا به شما می گوید که یک تابع تعریف نشده را صدا می زنید! چرا؟ ما که این تابع را بالاتر تعریف کرده ایم. مشکل بحث scope هست. از آنجایی که این متد در کلاس ما به صورت protected تعریف شده است، در هیچ نقطه ای در خارج از کلاس برای ما در دسترس نخواهد بود.

یادآوری: برای درک این نکته باید از قبل با مبحث scope در برنامه نویسی PHP آشنایی داشته باشید چرا که همانطور که قبلا گفتیم این دوره برای افراد مبتدی در نظر گرفته نشده است. برای یادگیری و اطلاعات بیشتر میتوانید در اینترنت جست و جو کنید و یا دوره ی برنامه نویسی PHP روکسو را تهیه کنید.

نتیجه 4: نتیجه ی این دستور متن زیر خواهد بود:

This is a Public methodThis is a Private methodThis is a Protected method

سوال: چرا این جملات به هم چسبیده اند؟

پاسخ: مانند دفعه ی قبل متذکر می شویم که با اینتر زدن و اسپیس گذاشتن در سورس کد نمی شود در خروجی HTML نیز فاصله ایجاد کرد. کامپیوتر توانایی درک صحیح نوشتن متن انسانی را ندارد. پس برای این کار میتوانید از دستوراتی مثل PHP_EOL و یا امثال آن استفاده کنید (مراجعه شود به دوره ی آموزشی روکسو).

نکته ی پایانی:

زبان PHP مانند اکثر زبان های دیگر، از مبحث وراثت استفاده می کند بنابراین زمانی که یک کلاس را extend کنید کلاس های زیرین یا همان کلاس های فرزند، تمام متدهای public و protected را از کلاسِ پدر به ارث می برند. زمانی که وارد مبحث وراثت (inheritance) شویم توضیحات بیشتری در این زمینه ارائه خواهد شد.

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

لینک های مفید:

دوره آموزش رایگان برنامه نویسی به زبان PHP به صورت متنی

دوره ویدیویی آموزش زبان برنامه نویسی PHP به صورت آنلاین

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری شی گرایی در PHP توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (3 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن
17 فروردین 1399
بخش constant خط سوم علامت دلار$ اضافیه...جواب سؤالات قبلی رو هم بدید لطفاً

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن
15 فروردین 1399
سلام. ببخشید من کجا میتونم تمرینات و مسائل Php رو پیدا کنم؟ سایت شما تمرین داره؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن
14 فروردین 1399
سلام. خداقوت لاین 29 عملگر -> به اشتباه بصورت > تایپ شده و اروری که نتیجه میدهد بخاطر همین اشتباه تایپی است. درحالی که اگر عملگر را صحیح تایپ کنید این ارور رو میده: Uncaught Error: Call to protected method... در واقع باید اینطوری تایپ بشه: $obj->my_protected_method();

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
27 فروردین 1399
با سلام دوست عزیز، از توجه شما ممنونم. بله کاراکتر - به اشتباه جا افتاده و حتما تصحیح میشه. روکسو، قسمت جداگانه ای به اسم تمرینات نداره اما در برخی از دوره ها سعی کردیم از تمرین استفاده کنیم. برای دوره ی PHP می تونید به این لینک برید (یک پروژه ی کامل هست): https://www.roxo.ir/series/object-oriented-php-mvc

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.