5. ابجکتها
5.1. هر متغیری میتواند به یک شیء با ویژگیها تبدیل شود (exemple_14)
<?php
// طبق طراحی، هر متغیر میتواند دارای ویژگیها باشد
$obj1->attr1 = "un";
$obj1->attr2 = 100;
// شیء را نمایش میدهد
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
//شیء را تغییر میدهد
$obj1->attr2+=100;
// شیء را نمایش میدهد
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
//مقدار object1 را به object2 اختصاص میدهد
$obj2 = $obj1;
// obj2 را تغییر میدهد
$obj2->attr2 = 0;
//هر دو شیء را نمایش میدهد
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
print "objet2=[$obj2->attr1,$obj2->attr2]\n";
// ارجاع object1 را به object3 اختصاص میدهد
$obj3 = &$obj1;
// obj3 را تغییر میدهد
$obj3->attr2 = 10;
//هر دو شیء را نمایش میدهد
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
print "objet3=[$obj3->attr1,$obj3->attr2]\n";
//آیا یک شی یک دیکشنری است؟
print count($obj1)."\n";
while (list($attribut, $valeur) = each($obj1))
print "obj1[$attribut]=$valeur\n";
//پایان
exit;
?>
نتایج:
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]
objet1=[un,10]
objet3=[un,10]
1
obj1[attr1]=un
obj1[attr2]=10
توضیحات
- خط ۴: نشانه $obj->attr به ویژگی attr از متغیر $obj اشاره دارد. اگر این ویژگی وجود نداشته باشد، ایجاد میشود و بدین ترتیب متغیر $obj به یک شیء دارای ویژگیها تبدیل میگردد.
- خط ۱۳: عبارت $obj2=$obj1، که در آن $obj1 یک شیء است، کپی شیءها از طریق مرجع است. بنابراین، $obj2 و $obj1 هر دو ارجاع به یک شیء واحد هستند. خود شیء را میتوان از طریق هر یک از این ارجاعات تغییر داد.
- خط ۲۰: عبارت $obj3=&$obj1 مرجع (آدرس) متغیر $obj1 را به $obj3 تخصیص میدهد. اگر $obj1 یک شیء باشد، که در اینجا چنین است، عبارت قبلی معادل $obj3=$obj1 است.
- خطوط ۲۸–۲۹: نشان میدهند که میتوان یک شیء را مانند یک دیکشنری پیمایش کرد. کلیدهای دیکشنری نام ویژگیها هستند و مقادیر دیکشنری، مقادیر همان ویژگیها میباشند.
- خط ۲۷: تابع count را میتوان روی یک شی اعمال کرد اما، برخلاف انتظار، تعداد ویژگیها را بازنمیگرداند. بنابراین، یک شی شباهتهایی با یک دیکشنری دارد اما خود یک دیکشنری نیست.
5.2. کلاس Person با هیچ ویژگی اعلامشدهای (exemple_15)
<?php
class Personne {
// ویژگیهای کلاس
// اعلامنشده – میتواند بهصورت پویا ایجاد شود
// متد
function identité() {
//ظاهراً از ویژگیهای موجود استفاده نمیکند
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// آزمایش
// ویژگیها عمومی هستند و میتوانند بهصورت پویا ایجاد شوند
$p = new Personne();
$p->prénom = "Paul";
$p->nom = "Langevin";
$p->âge = 48;
//فراخوانی متد
print "personne=" . $p->identité() . "\n";
// پایان
exit;
?>
نتایج:
توضیحات
- خطوط ۳–۱۳: یک کلاس Personne تعریف کنید. کلاس قالبی است که اشیاء از آن ایجاد میشوند. کلاس مجموعهای از ویژگیها و توابع است که به آنها متد گفته میشود. ویژگیها لازم نیست اعلام شوند.
- خطوط ۹–۱۲: متد identité مقادیر سه ویژگی را که در کلاس تعریف نشدهاند نمایش میدهد. کلمه کلیدی $this به شیئی اشاره دارد که متد بر روی آن اعمال میشود.
- خط ۱۷: یک شیء از نوع Personne با نام $p ایجاد میشود. کلمه کلیدی
newبرای ایجاد یک شیء جدید استفاده میشود. این عملیات یک مرجع به شیء ایجاد شده (یعنی یک آدرس) را برمیگرداند. نگارشهای مختلفی امکانپذیر است:new Personne(),new Personne,new personne. نام کلاس به بزرگی و کوچکی حروف حساس نیست. - خطوط ۱۸–۲۰: سه ویژگی مورد نیاز متد identité در داخل شی $p ایجاد میشوند.
- خط ۲۲: متد identité از کلاس Personne بر روی شی $p اعمال میشود. در کد (خطوط ۹–۱۱) متد identité، $this به همان شیء اشاره میکند که $p به آن اشاره دارد.
5.3. کلاس Person با ویژگیهای اعلامشده (exemple_16)
<?php
class Personne {
//ویژگیهای کلاس
var $prénom;
var $nom;
var $âge;
// متد
function identité() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// آزمایش
// ویژگیها عمومی هستند
$p = new Personne();
$p->prénom = "Paul";
$p->nom = "Langevin";
$p->âge = 48;
// فراخوانی متد
print "personne=" . $p->identité() . "\n";
// پایان
exit;
?>
نتایج:
توضیحات
- خطوط ۶–۸: ویژگیهای کلاس بهطور صریح با استفاده از کلمهٔ کلیدی var اعلام شدهاند.
5.4. کلاس Person با یک سازنده (exemple_17)
مثالهای قبلی کلاسهای غیرمعمول Personne را مانند آنچه در PHP 4 یافت میشود، نشان دادند. پیروی از این مثالها توصیه نمیشود. اکنون یک کلاس Personne را ارائه میکنیم که با بهترین شیوههای PHP 5 مطابقت دارد:
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرنده و تنظیمکننده
public function getPrénom() {
return $this->prénom;
}
public function getNom() {
return $this->nom;
}
public function getAge() {
return $this->âge;
}
public function setPrénom($prénom) {
$this->prénom = $prénom;
}
public function setNom($nom) {
$this->nom = $nom;
}
public function setAge($age) {
$this->âge = $age;
}
// سازنده
function __construct($prénom, $nom, $âge) {
// ما تنظیمکنندهها را بررسی میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// متد toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// آزمایش
//ایجاد یک شیء شخص
$p = new Personne("Paul", "Langevin", 48);
// هویت این شخص
print "personne=$p\n";
// تغییر سن
$p->setAge(14);
// هویت شخص
print "personne=$p\n";
//پایان
exit;
?>
نتایج:
نظرات
- خطوط ۳–۴۸: کلاس Personne
- خطوط ۶–۸: ویژگیهای خصوصی کلاس. این ویژگیها تنها در داخل کلاس قابل مشاهده هستند. کلمات کلیدی دیگری که میتوان استفاده کرد عبارتند از:
- public: صفت را به یک صفت عمومی تبدیل میکند که از خارج کلاس قابل مشاهده است
- protected: صفت را به یک صفت محافظتشده تبدیل میکند که از داخل کلاس و کلاسهای مشتقشده از آن قابل مشاهده است.
- از آنجا که ویژگیها خصوصی هستند، نمیتوان از خارج کلاس به آنها دسترسی داشت. بنابراین، کد زیر قابل نوشتن نیست:
در اینجا، ما خارج از کلاس Personne هستیم. از آنجایی که ویژگی nom خصوصی است، خط ۲ نادرست است. دو روش برای مقداردهی اولیه فیلدهای خصوصی شیء $p وجود دارد:
- (ادامه)
- از متدهای عمومی set و get (نام این متدها میتواند هر چیزی باشد) در خطوط 11–33 استفاده کنید. سپس میتوانیم بنویسیم:
- (ادامه)
- از سازنده در خطوط ۳۶–۴۱ استفاده کنید. سپس به این صورت مینویسیم:
کد بالا بهطور خودکار متد کلاس Personne به نام __construct را فراخوانی میکند.
- خط ۵۴: این خط شخص $p را به صورت یک رشتهٔ کاراکتری نمایش میدهد. برای این کار، از متد کلاس Personne با نام __toString استفاده میشود.
5.5. کلاس Person با بررسیهای اعتبار در سازنده (exemple_18)
کانستراکتور یک کلاس مکان مناسبی برای بررسی صحت مقادیر اولیهٔ یک شیء است. با این حال، یک شیء میتواند از طریق متدهای set یا معادل آن نیز مقداردهی اولیه شود. برای جلوگیری از تکرار همان بررسیها در دو مکان مختلف، این بررسیها باید در متدهای set قرار داده شوند. اگر مقدار اولیه یک شیء نادرست تشخیص داده شود، یک استثنا پرتاب خواهد شد. در اینجا یک مثال آورده شده است:
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرنده و تنظیمکننده
public function getPrénom() {
return $this->prénom;
}
public function getNom() {
return $this->nom;
}
public function getAge() {
return $this->âge;
}
public function setPrénom($prénom) {
// نام اول نباید خالی باشد
if (!preg_match("/^\s*(.+?)\s*$/", $prénom, $champs)) {
throw new Exception("Le prénom doit être non vide");
} else {
$this->prénom = $champs[1];
}
}
public function setNom($nom) {
// نام خانوادگی نباید خالی باشد
if (!preg_match("/^\s*(.+?)\s*$/", $nom, $champs)) {
throw new Exception("Le nom doit être non vide");
} else {
$this->nom = $champs[1];
}
}
public function setAge($âge) {
// سن باید معتبر باشد
if (!preg_match("/^\s*(\d+)\s*$/", $âge, $champs)) {
throw new Exception("L'âge doit être un entier positif ou nul");
} else {
$this->âge = $champs[1];
}
}
// سازنده
function __construct($prénom, $nom, $âge) {
// ما از سترها استفاده میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
//روش toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// آزمایش
// ایجاد یک شیء Person
$p = new Personne("Paul", "Langevin", 48);
// هویت این شخص
print "personne=$p\n";
// ایجاد یک شیء Person نادرست
try {
$p = new Personne("xx", "yy", "zz");
} catch (Exception $e) {
print $e->getMessage();
}
// پایان
exit;
?>
نتایج:
توضیحات
- خطوط ۲۳–۳۰: مقداردهی اولیه ویژگی prénom و بررسی مقدار اولیه
- خط ۲۵: استفاده از یک عبارت منظم. نام اول دنبالهای از یک یا چند کاراکتر است که ممکن است قبل یا بعد از آن فاصلهها قرار داشته باشند.
- خط ۲۶: اگر نام خانوادگی خالی باشد، یک استثنا پرتاب میشود؛ در غیر این صورت، نام اول ذخیره میشود (خط ۲۸)
- خط ۶۶: استفاده از سازنده کلاس Personne
- خط ۶۸: استفاده از متد __toString از کلاس Personne
- خطوط ۷۰–۷۴: رسیدگی به هر استثنایی که توسط سازنده کلاس Personne پرتاب میشود.
5.6. افزودن متدی که بهعنوان سازندهٔ دوم عمل میکند (exemple_19)
در PHP 5، امکان داشتن چندین سازنده با پارامترهای متفاوت که اجازه میداد یک شیء به روشهای گوناگون ساخته شود، وجود ندارد. بنابراین میتوان از متدها برای عمل بهعنوان سازنده استفاده کرد:
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرنده و تنظیمکننده
public function getPrénom() {
return $this->prénom;
}
….
// سازنده
function __construct($prénom, $nom, $âge) {
// ما از متدهای ستکننده استفاده میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// متد
public function initWithPersonne($p) {
// شیء فعلی را با یک شخص مقداردهی اولیه میکند $p
$this->__construct($p->prénom, $p->nom, $p->âge);
}
// روش toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// آزمایش
// ایجاد یک شیء Person
$p = new Personne("Paul", "Langevin", 48);
// هویت این شخص
print "personne=$p\n";
// ایجاد شخص دوم
$p2 = new Personne("Laure", "Adeline", 67);
// ابتداییسازی شخص اول با مقادیر شخص دوم
$p->initWithPersonne($p2);
// تأیید
print "personne=$p\n";
// پایان
exit;
?>
نتایج:
توضیحات
- خطوط 26–29: متد initWithPersonne برای تخصیص مقادیر ویژگیهای یک شیء دیگر (Personne) به شیء فعلی استفاده میشود. در اینجا، این متد کانستراکتور __construct را فراخوانی میکند، اما این امر اجباری نیست.
5.7. یک آرایه از اشیاء Person (exemple_20)
مثال زیر نشان میدهد که میتوان آرایههایی از اشیاء داشت.
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرنده و تنظیمکننده
public function getPrénom() {
return $this->prénom;
}
...
// سازنده
function __construct($prénom, $nom, $âge) {
// ما روشهای ستکننده را بررسی میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// روش
public function initWithPersonne($p) {
….
}
// متد toString
function __toString() {
...
}
}
// آزمایش
// ایجاد آرایهای از اشیاء Person
$groupe = array(new Personne("Paul", "Langevin", 48), new Personne("Sylvie", "Lefur", 70));
// هویت این افراد
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// پایان
exit;
?>
نتایج:
نظرات
- خط ۳۹: ایجاد آرایهای از ۲ نفر
- خط ۴۲: تکرار در آرایه
- خط ۴۳: $groupe[$i] یک شی از نوع Personne است. متد __toString برای نمایش آن استفاده میشود.
5.8. ایجاد کلاسی مشتقشده از کلاس Person (exemple_21)
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرنده و تنظیمکننده
public function getPrénom() {
return $this->prénom;
}
...
// سازنده
function __construct($prénom, $nom, $âge) {
// ما از متدهای ستر استفاده میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// متد
public function initWithPersonne($p) {
// شیء فعلی را با یک شخص مقداردهی اولیه میکند $p
$this->__construct($p->prénom, $p->nom, $p->âge);
}
// روش toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// یک کلاس مشتقشده از Person
class Enseignant extends Personne {
//ویژگیها
private $discipline; // موضوع تدریسشده
// گیرندهها و تنظیمکنندهها
public function getDiscipline() {
return $this->discipline;
}
public function setDiscipline($discipline) {
$this->discipline = $discipline;
}
// سازنده
public function __construct($prénom, $nom, $âge, $discipline) {
// ویژگیهای والد
parent::__construct($prénom, $nom, $âge);
// سایر ویژگیها
$this->setDiscipline($discipline);
}
// پوشاندن تابع __toString کلاس والد
public function __toString() {
return "[" . parent::__toString() . ",$this->discipline]";
}
}
// آزمایش
// ایجاد یک جدول از اشیاء Person و مشتقات آن
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70));
// هویت این افراد
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// پایان
exit;
?>
نتایج:
توضیحات
- خطوط ۳–۳۵: کلاس Personne
- خط ۳۸: کلاس Enseignant از کلاس Personne. ارث میبرد. کلاس مشتق Enseignant ویژگیها و متدهای کلاس والد خود را به ارث میبرد.
- خط ۴۱: کلاس Enseignant یک ویژگی جدید به نام discipline اضافه میکند که مختص آن است
- خط ۵۵: سازنده کلاس Enseignant چهار پارامتر میگیرد
- ۳ برای инициализация کلاس والد آن (نام، نام خانوادگی، سن)
- ۱ برای inizialization خود (subject)
- خط ۵۷: کلاس مشتق شده از طریق کلمه کلیدی
parent::به متدها و سازندههای کلاس والد دسترسی دارد. در اینجا، پارامترها (نام، نام خانوادگی، سن) به سازنده کلاس والد ارسال میشوند. - خط ۶۴: متد __toString از کلاس مشتق از متد __toString از کلاس والد استفاده میکند.
- خط ۷۱: یک آرایه شامل یک شی Enseignant و یک شی Personne.
- خط ۷۴: عناصر آرایه بهصورت متوالی بررسی میشوند
- خط ۷۵: متد __toString برای هر عنصر $groupe[$i] فراخوانی میشود. کلاس Personne دارای متدی به نام __toString است. کلاس Enseignant دو متد دارد: متد کلاس والد و متد خود. ممکن است این سؤال پیش بیاید که کدام یک فراخوانی خواهد شد. اجرا نشان میدهد که متد کلاس Enseignant فراخوانی شده است. این امر همیشه صادق است: هنگامی که یک متد روی یک شی فراخوانی میشود، به ترتیب زیر در آن جستجو میشود: در خود شی، در کلاس والد آن در صورت وجود، سپس در کلاس والدِ والد، و غیره. جستجو به محض یافتن متد متوقف میشود.
5.9. ایجاد یک کلاس ثانویه مشتق شده از کلاس Person (exemple_22)
مثال زیر کلاسی به نام Etudiant را مشتق از کلاس Personne ایجاد میکند:
<?php
class Personne {
// ویژگیهای کلاس
private $prénom;
private $nom;
private $âge;
// گیرندهها و تنظیمکنندهها
public function getPrénom() {
return $this->prénom;
}
...
// سازنده
function __construct($prénom, $nom, $âge) {
// ما از متدهای ستر استفاده میکنیم
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// متد
public function initWithPersonne($p) {
// شیء فعلی را با یک شخص مقداردهی اولیه میکند $p
...
}
// روش toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// یک کلاس مشتقشده از 'person'
class Enseignant extends Personne {
//ویژگیها
private $discipline; // موضوع تدریسشده
// گیرندهها و تنظیمکنندهها
...
// سازنده
public function __construct($prénom, $nom, $âge, $discipline) {
// ویژگیهای والد
parent::__construct($prénom, $nom, $âge);
// سایر ویژگیها
$this->setDiscipline($discipline);
}
// پوشاندن تابع _identité__toString کلاس والد
public function __toString() {
return "[" . parent::__toString() . ",$this->discipline]";
}
}
// کلاسی مشتقشده از Person
class Etudiant extends Personne {
// ویژگیها
private $formation; // موضوع تدریسشده
// گیرنده و تنظیمکننده
public function getFormation() {
return $this->formation;
}
public function setFormation($formation) {
$this->formation = $formation;
}
// سازنده
public function __construct($prénom, $nom, $âge, $formation) {
// ویژگیهای والد
parent::__construct($prénom, $nom, $âge);
// سایر ویژگیها
$this->setFormation($formation);
}
// پوشاندن تابع __toString کلاس والد
public function __toString() {
return "[" . parent::__toString() . ",$this->formation]";
}
}
// آزمایش
// ایجاد آرایهای از اشیاء شخص و اشیاء مشتقشده
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70), new Etudiant("Steve", "Boer", 23, "iup2 qualité"));
// هویت این افراد
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// پایان
exit;
?>
نتایج:
groupe[0]=[[Paul,Langevin,48],anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[[Steve,Boer,23],iup2 qualité]
5.10. رابطها (exemple_23)
یک رابط ساختاری است که پروتوتایپ متدها را تعریف میکند. کلاسی که یک رابط را پیادهسازی میکند، کد تمام متدهای موجود در آن رابط را تعریف میکند.
<?php
//یک رابط
interface IExemple {
function ajouter($i, $j);
function soustraire($i, $j);
}
// پیادهسازی ۱ رابط
class Classe1 implements IExemple {
public function ajouter($a, $b) {
return $a + $b + 10;
}
public function soustraire($a, $b) {
return $a - $b + 20;
}
}
// پیادهسازی ۲ رابط
class Classe2 implements IExemple {
public function ajouter($a, $b) {
return $a + $b + 100;
}
public function soustraire($a, $b) {
return $a - $b + 200;
}
}
// تابع
function calculer($a, $b, IExemple $interface) {
print $interface->ajouter($a, $b)."\n";
print $interface->soustraire($a, $b)."\n";
}
// ------------------- main
// ایجاد ۲ شیء از نوع Class1 و Class2
$c1 = new Classe1();
$c2 = new Classe2();
// فراخوانی تابع 'calculate'
calculer(4, 3, $c1);
calculer(14, 13, $c2);
?>
نتایج
توضیحات
- خطوط ۴–۸: رابط IExemple دو متد را تعریف میکند: تابع ajouter (خط ۵) و تابع soustraire (خط ۷). این رابط کد این متدها را تعریف نمیکند. این کار توسط کلاسهایی که این رابط را پیادهسازی میکنند انجام میشود.
- خط ۱۱: کلاس Classe1 رابط IExemple را پیادهسازی میکند. بنابراین کد متدهای ajouter (خط ۱۳) و soustraire (خط ۱۷) را تعریف میکند.
- خطوط ۲۴–۳۴: همین امر در مورد کلاس Classe2 نیز صدق میکند.
- خط ۳۷: متد calculer سه پارامتر میگیرد: دو عدد صحیح، $a و $b، و یک شیء $interface که رابط IExemple را پیادهسازی میکند. میشد
function calculate($a, $b, $interface)را بدون مشخص کردن نوعIExempleبرای پارامتر$interfaceنوشت. با مشخص کردن آن، به تفسیرگر PHP اجازه میدهیم تا بررسی کند که پارامتر واقعی در واقع یک شیء پیادهساز رابط IExemple است. - خطوط ۳۸–۳۹: استفاده از متدهای ajouter و soustraire از شیء $interface. از آنجا که این شیء رابط IExemple را پیادهسازی میکند، میدانیم که این دو متد را دارد.
- خطوط ۴۴–۴۵: ایجاد دو شیء از انواع مختلف که هر دو رابط IExemple را پیادهسازی میکنند.
- خط ۴۷: شیء $c1 از نوع Classe1 و پیادهساز رابط IExemple به تابع calculer ارسال میشود.
- خط ۴۸: کنترل به تابع calculer ارسال میشود؛ شیء $c2 از نوع Classe2، رابط IExemple را پیادهسازی میکند.