לפעמים צריך ליצור מחלקה חדשה שמאוד דומה למחלקה אחרת שיצרנו כבר או מחלקה חדשה שמוסיפה אלמנטים למחלקה שיצרנו. יהיה זה נוח אילו המחלקה החדשה שניצור תקבל ב"הורשה" את האלמנטים של המחלקה הקיימת, ועל המחלקה החדשה נשנה ו/או נוסיף אלמנטים.
PHP מאפשרת ליצור מחלקה חדשה שתרחיב מחלקה קיימת באמצעות extends, ובעצם "תירש" את האלמנטים של המחלקה הקיימת. המחלקה החדשה תכיל בתוכה את כל המשתנים והפונקציות מן מחלקת הבסיס (שממנה יורשים), שאותם ניתן לשנות בהתאם למטרות המחלקה החדשה, וניתן להוסיף עליהם משתנים ופונקציות הייחודיות רק למחלקה החדשה. כדי לשנות פונקציה ממחלקת הבסיס, אנו מגדירים את אותה הפונקציה (אותו שם) במחלקה החדשה, ועל-ידי כך משכתבים את הפונקציה. ב-PHP ניתן לרשת אך ורק מחלקה אחת בכל הגדרה של מחלקה חדשה.
נמשיך את הדוגמא הקודמת של המחלקה Book ונרחיב אותה למחלקה LibraryBook, ספר ספריה:
<?php class LibraryBook extends Book
/*
הגדרת מחלקה חדשה היורשת מחלקה קיימת.
*/
{ var$lib_id;
/*
הוספת משתנה מחלקה חדש למחלקה החדשה.
*/
var$lib_borrowed;
function LibraryBook($name,$author,$id,$borrowed=false)
/*
הגדרת פונקציית בנאי למחלקה החדשה. פונקציית הבנאי של מחלקת הבסיס לא משמשת יותר כבנאי אחרי ההורשה.
*/
{ if ($author=='') //if no author specified $author='unknown'; $this->Book($name,$author);
/*
קריאה לפונקציית הבנאי של מחלקת הבסיס. מאתחלת את המשתנים של מחלקת הבסיס.
*/
$this->lib_id=$id;
/*
אתחול משתני המחלקה החדשה.
*/
$this->lib_borrowed=$borrowed; }
function BorrowBook()
/*
הגדרת פונקציית מחלקה חדשה. פונקציה זו מחזירה ערך.
*/
{ if ($this->lib_borrowed) //if the book is borrowed returnfalse; //can not borrow the book $this->lib_borrowed=true; //the book is now borrowed returntrue; //can borrow the book }
function PrintBookDetails()
/*
שכתוב פונקציה ממחלקת הבסיס כדי להתאים אותה למחלקה החדשה.
*/
{ echo "name: ".$this->book_info['name']."<BR>author: ".$this->book_info['author']."<BR>id: ".$this->lib_id."<BR>"; if ($this->lib_borrowed) echo "* <I>the book is not available.</I>"; else echo "* <I>the book is available.</I>"; echo "<BR>--------------------<BR>\n"; } }
$bk1=new LibraryBook("20 miles under the water","Jul Vern",1234);
/*
יצירת מופע של המחלקה החדשה. שולחים ארגומנטים לפונקציית הבנאי שלה.
echo "<BR><B>"; echo "-Student: \"May I borrow book 1 ?\"<BR>\n"; if ($bk1->BorrowBook()==true) echo "-Librarian: \"Yes, enjoy!\"<BR>\n"; else echo "-Librarian: \"Sorry, you cannot. It is already borrowed.\"<BR>\n"; echo "-Student: \"May I borrow book 2 ?\"<BR>\n"; if ($bk2->BorrowBook()==true) echo "-Librarian: \"Yes, enjoy!\"<BR>\n"; else echo "-Librarian: \"Sorry, you cannot. It is already borrowed.\"<BR>\n"; echo "</B><BR>";
ב-PHP3 פונקציית הבנאי של המחלקה המורחבת היא הפונקציה ששמה זהה לשם המחלקה החדשה, גם אם הפונקציה הזו התקבלה בהורשה. כך גם הדבר ב-PHP4. אך ההבדל הוא שאם לא נמצאית פונקציה עם שם זהה לשם המחלקה, ב-PHP4 יקחו את פונקציית הבנאי של מחלקת הבסיס, וב-PHP3 לא יקחו פונקציה אחרת ולא תהיה פונקציית בנאי. ניתן דוגמא להבהרת העניין:
<?php class A { function A() { echo "I am the constructor of class A.<BR>\n"; }
function B() { echo "I am a regular function of class A named B. I am not the constructor of class A.<BR>\n"; } }
class B extends A { function C() { echo "I am a regular function of class B.<BR>\n"; } }
class C extends A { function D() { echo "I am a regular function of class C.<BR>\n"; } }
לא תמצא פונקציה עם שם הזהה לשם המחלקה. ב-PHP3: לא תהיה פונקציית בנאי למחלקה C. ב-PHP4: פונקציית הבנאי של מחלקת הבסיס A תהפוך להיות לפונקציית הבנאי של המחלקה C.
*/
?>
ב-PHP, בניגוד לשפת C++, אין צורך בפונקציות הורסות (destructors), כי PHP הורסת את מופע המחלקה באופן אוטומטי.
תגובות בנושא
סוףסוף הבנתי
06-12-03 08:00 alex9913
#903
לא מצאתי עוד מקום שמסביר כל כך טוב על קלאסים,
אפילו ספר ענק שקניתי לא מסביר את "חוקי המשחק" עם המחלקות בצורה כל כך בהירה וטובה.
כל כבוד.
virtual functions
02-11-03 19:01 elad leibovitz
#1330
שלום, הייתי רוצה לדעת איך מממשים פונקציה וירטואלית? האם פשוט רושמים את הגדרתה ומשאירים את גוף הפונקציה ריק? והאם הוירטואליות מתבטאת כמו ב- C++? כלומר האם כאשר אני מצביע עם פונטר מסוג אבא על בן יה יעבוד והאם זה גם יפעיל את הפונקציה של הבן אם הפונקציה תהיה וירטואלית באבא?
אודה לך אם תענה בהקדם, תודה.