TypeScript - חלק ג': הגדרת Interface

בפוסט הקודם הסברתי על Class ב-TypeScript, כעת אמשיך להסביר על Interface.

מה זה Interface ולמה אנחנו צריכים את זה?

Interface הוא ממשק שמכיל הגדרות (כמו פונקציות ומאפיינים) ללא מימוש אלא רק את החתימה שלהם הכוללת את השם ואת הפרמטרים שהיא מקבלת, והוא סוג של חוזה בין כל ה-Class-ים שיורשים ממנו כך שהם מתחייבים לממש את כל מה שנדרש מהם והוא אחד העקרונות בתכנות מונחה עצמים.

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

מכיוון ש-JavaScript היא שפה דינמית אין בה את האפשרות ל-Interface כמשהו מחייב כמו בשפות אחרות (כמו ב- C Sharp למשל) ולכן ההוספה של Interface ל-TypeScript יכולה לעזור לנו בצורה משמעותית כאשר נרצה להשתמש בכך.

 

 

איך כותבים Interface ב TypeScript?

Interface נכתב על ידי מילת המפתח interface ולאחר מכן שמו של ה-Interface, כאשר נהוג להוסיף בתחילת השם את האות I בשביל הנוחות והסדר.

בדוגמא שלנו נגדיר Interface בשם IAnimal שיהיה הבסיס לכל ה-Class-ים של בעלי החיים שניצור בהמשך ונגדיר לו שכל בעל חיים שירצה לממש את IAnimal יהיה חייב שיהיה לו את המשתנים name (שמו), Gender (זכר/נקבה) ו-BirthYear (שנת לידה). כמו כן נרצה להגדיר את הפונקציה speak, שלא מקבלת פרמטרים אך מחזירה מחרוזת (string)

interface IAnimal {
    name: string;
    gender: string;
    birthYear: number;
    speak: () => string;
}

 

כעת השלב הבא הוא לייצר Class שיורש מ- IAnimal, הדוגמא הראשונה שלנו תהיה חתול ולכן נקרא ל-Class החדש שלנו Cat. 

על מנת להגדיר שה-Class החדש שלנו יורש מ- IAnimal, צריך לרשום לאחר שמו של ה-Class את מילת המפתח implements ולאחר מכן את שם ה- Interface שבמקרה שלנו הוא IAnimal.

class Cat implements IAnimal {

}

 

מאחר והגדרנו ש- Cat יורש מ- IAnimal אך לא מימשנו ב-Class אף אחד מהמשתנים והפונקציות שנדרשו על ידי ה-Interface כבר נקבל את השגיאה:

//Error: Class 'Cat' incorrectly implements interface 'IAnimal'. Property 'name' is missing in type 'Cat'.

 

וכעת נראה איך Cat נראה לאחר שנוסיף לו את מה שה-Interface דורש מאיתנו:

class Cat implements IAnimal {
    name: string;
    gender: string;
    birthYear: number;
    speak(): string { return "Meow"; }
}

 

כעת נראה איך ניצור אוביקט של של Cat. לחתול החדש שלנו נקרא Garfield

var garfield = new Cat();
garfield.name = "Garfield";
garfield.gender = "Male";
garfield.birthYear = 1978;

console.log(garfield.speak());  //Meow

garfield.speak = function () { return "I know Hebrew"; };
console.log(garfield.speak());  //I know Hebrew

קצת הסבר על מה עשיתי בדוגמא של Garfield:

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

בשורות 2-4 הגדרנו את שמו, מינו ושנת הלידה של החתול שלנו.

בשורה 6 הפעלנו את הפונקציה של speak וקיבלנו את התשובה מה-Cat שהיא "Meow".

בשורות 8-9 החלטנו שהחתול שלנו יודע קצת יותר מלהגיד "מיאו" ולכן דרסנו את הפונקציה הקודמת בפונקציה חדשה שמחזירה "I know Hebrew".

שימו לב שאם היינו מגדירים שהפונקציה speak החדשה שלנו מחזירה מספר, למשל 5, היינו מקבלים את השגיאה הבאה מכיוון שהגדרנו (גם ב-Cat וגם ב-IAnimal) שהפונקציה צריכה להחזיר מחרוזת. הערה זו רלוונטית גם אם זה היה מוגדר רק באחד מהם, למשל, אם ב-Cat לא היינו מגדירים שהיא חייבת string זה עדיין היה חובה כי כך נדרש על ידי ה-Interface שהוא יורש ממנו. כנ"ל לגבי המצב ההפוך שה-Interface לא היה דורש שהפונקציה speak תחזיר מחרוזת אך ה-Class כן היה דורש.

garfield.speak = function () { return 5; };
//Error: Type '() => number' is not assignable to type '() => string'. Type 'number' is not assignable to type 'string'.

 

 

 

בדוגמא האחרונה שלנו ניצור Class נוסף עבור ג'ירפות כאשר היא יורשת מה-Interface שלנו IAnimal בדומה ל-Cat.

לאחר מכן ניצור instance של ג'ירפה שנקרא לה בשם יפה, שהיא נקבה שנולדה בשנת 2010 וכמו שכולם יודעים, הג'ירפה יפה לא עושה קולות כך שכאשר נבקש ממנה לדבר היא תחזיר "Doesn't make sounds".

class Giraffe implements IAnimal {
    name: string;
    gender: string;
    birthYear: number;
    speak(): string { return "Doesn't make sounds"; }
}

var yafa = new Giraffe();
yafa.name = "Yafa";
yafa.gender = "Female";
yafa.birthYear = 2010;

 

 

תגיות:

הוסף תגובה