אתה נמצא כאן יסודות השפה  >>  מחלקות ואובייקטים  >>  הורשה

הורשה

לפעמים צריך ליצור מחלקה חדשה שמאוד דומה למחלקה אחרת שיצרנו כבר או מחלקה חדשה שמוסיפה אלמנטים למחלקה שיצרנו. יהיה זה נוח אילו המחלקה החדשה שניצור תקבל ב"הורשה" את האלמנטים של המחלקה הקיימת, ועל המחלקה החדשה נשנה ו/או נוסיף אלמנטים.

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
  
         return false; //can not borrow the book
  
      $this->lib_borrowed=true; //the book is now borrowed
  
      return true; //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);
/*יצירת מופע של המחלקה החדשה.
שולחים ארגומנטים לפונקציית
הבנאי שלה.
*/

  $bk2=new LibraryBook("catch 22","",4321,true);
  $bk1->PrintBookDetails();
  $bk2->PrintBookDetails();
  
  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>";
  
  $bk1->PrintBookDetails();
  $bk2->PrintBookDetails();
?>

ב-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";
     }
  }
  
  echo "<BR><B>creating class B:</B> ";
  $b=new B;
/*התנהגות זהה גם ב-PHP3 וגם ב-PHP4:
תמצא פונקציה הזהה לשם המחלקה (B),
ופונקציה זו תהפוך לפונקציית הבנאי של B
על-אף שעברה בירושה.
*/

  echo "<BR><B>creating class C:</B> ";
  $c=new C;
/*לא תמצא פונקציה עם שם הזהה לשם המחלקה.
ב-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++? כלומר האם כאשר אני מצביע עם פונטר מסוג אבא על בן יה יעבוד והאם זה גם יפעיל את הפונקציה של הבן אם הפונקציה תהיה וירטואלית באבא?
אודה לך אם תענה בהקדם, תודה.


לדף הקודםהגדרת מחלקה -הקודם
לתחילת הדףלתחילת הדף
הבא- קריאה לפונקציית מחלקהלדף הבא