מדריך PHP

מדריך PHP: תכנות מונחה עצמים – interface

‏ • Internet Israel

אתם בוודאי זוכרים שבמאמר על class אבסטרקטי הראיתי דרך ליצור מתודה אבסרקטית על מנת לוודא שב-class שיורש מה-class האבסטרקטי תהיה בוודאות גם מתודה כמתודה האבסטרקטית. אינטרפייס עושה משהו דומה, רק בלי class אבסטרקטי.

תודו שזה משפט מחץ. בואו ונמשיך לקרוא על מנת להבין.

כאשר אני יוצר אינטרפייס מסוים ומיישם אותו ב-class מסוים, אני יכול לוודא שבאותו class יש את המתודות שאנו רוצים שיהיו לו.

אתם יודעים מה? בואו נדגים את זה. נניח שאני רוצה שיהיו שני מתודות מסוג c_method ו-d_method כאשר ל-d_method צריכים שני ארגומנטים. אני אצור אינטרפייס הכולל את המתודות האלו:

<?php

interface my_interface {
    public function c_method();
    
    public function d_method($arg1, $arg2);
}

כך יוצרים interface, בדיוק כמו class, שימו לב שבאינטרפייס אין private functions.

עכשיו בואו נממש את ה-interface, עושים זאת כך:

<?php
interface my_interface {
    public function c_method();
    
    public function d_method($arg1, $arg2);
}

class a implements my_interface  {
    public function c_method() {
        return "This is C!";
    }
    public function d_method($arg1, $arg2) {
        return "This is d: $arg1 , $arg2";
    }
}

$instance = new a();

print $instance->d_method('foo','bar');

וכך בעצם יוצרים מימוש של אינטרפייס, אם ננסה ליצור את class a ללא אחת המתודות המפורטות ב-interface שלו, נקבל שגיאה.

נשאלת השאלה למה להשתמש בדיוק ב-interface כאשר אנו יכולים להשתמש במתודה אבסטרקטית? התשובה היא שהשימוש ב-interface לא מחייב אותנו לירושה מ-class אבסטרקטי מסוים. וכך שני classים שלא יורשים מאותו class יכולים להכיל interface דומה. בפועל השימוש ב-interface מאפשר לנו לא לנפח את class האב במתודות מיותרות.

אפשר להרחיב את כל נושא ה-interface אם נשתמש ב- Type Hintingשמאפשרת לנו גם לציין לא רק את המתודה שחייבים להשתמש בה, אלא גם איזה input היא צריכה לקבל, ממש כמו בשפות אמיתיות 😉

איך משתמשים בזה? מאד פשוט, שימו לב לדוגמא הבאה שבה אני מציין שהארגומנט של המתודה המצויינת ב-interface חייב להיות מסוג array:

<?php
interface my_interface {
    public function d_method(array $arg1);
}

class a implements my_interface  {
    public function d_method(array $arg1) {
        return "This is d: $arg1[1]";
    }
}

$instance = new a();

$arg1 = array(1=>'foo', 2=>'bar');

print $instance->d_method($arg1);

אם תקחו את הקוד הזה ותנסו להציב במקום המערך שיצרתי סתם משתנה, תקבלו שגיאה.

בנוסף לפירוט של מערך או null, אפשר גם לציין גם שם של class שאנו רוצים לקבל. וזה כבר ממש נחמד, שימו לב לדוגמא הבאה:

<?php
interface my_interface {
    public function a_method(b $arg1);
}

class a implements my_interface  {
    public function a_method(b $arg1) {
        return 'This is b: '.$arg1->var;
    }
}

class b {
    public $var = 'hello';
}

$b = new b();

$instance = new a();

print $instance->a_method($b);

מה הולך פה? ב-interface ציינתי שאני רוצה שכל מי שמממש את ה-interface שלי יכיל מתודה ששמה הוא a_method והיא מקבל ארגומנט אחד מסוג class b. בשאר יש כבר יישום פשוט של זה, אם אני אנסה להעביר instance של משהו שהוא לא class b לתוך מתודת a_method, אני אקבל שגיאה בלבד.

לא חייבים להשתמש ב-Type Hinting רק ב-interface אלא אפשר להשתמש בו גם במתודות רגילות על מנת לוודא שאם מעבירים לנו משתנה הוא יהיה instance של class מסוים. למשל:

<?php
class a {
    public function a_method(b $arg1) {
        return 'This is b: '.$arg1->var;
    }
}

class b {
    public $var = 'hello';
}

$b = new b();

$instance = new a();

print $instance->a_method($b);

ואני רוצה לראות שתנסו להכניס משהו במקום instance של b ולא תקבלו איזו הודעת שגיאה.

תגיות: , ,

רן בר-זיק

מתכנת PHP מנוסה ובעל ידע רב בפיתוח לאינטרנט על בסיס LAMP. מומחה במערכות דרופל, ג'ומלה ו-וורדפרס. שולט היטב בכל מה שקשור לפרונט אנד: JavaScript: jQuery ו-MooTools,ActionScript 2/3 וכמובן HTML 5 + CSS 3.אינטרנט ישראל: www.internet-israel.com

תגובות בפייסבוק