1. מה זה תכנות מונחה עצמים (OOP)?
תכנות מונחה עצמים (Object-Oriented Programming, OOP) הוא פרדיגמה בתכנות שבה בונים את הקוד סביב אובייקטים. אובייקט הוא מבנה נתונים שמייצג ישות מסוימת וכולל מאפיינים (נתונים) ו-שיטות (פונקציות שמבצעות פעולות על הנתונים).
ב-JavaScript, התכנות מונחה העצמים מתבסס על אובייקטים, ודרך נוחה ליצירת אובייקטים היא שימוש ב-Classes (מחלקות).
2. יצירת אובייקט פשוט ב-JavaScript
לפני שנעבור לשימוש במחלקות, נזכיר שאובייקטים ב-JavaScript הם מבני נתונים חשובים מאוד.
דוגמה ליצירת אובייקט:
let person = {
name: "Alice",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet(); // מציג "Hello, my name is Alice"
הסבר:
- האובייקט
person
כולל מאפיינים כמוname
ו-age
. - בנוסף, יש לו שיטה (פונקציה) בשם
greet
שמדפיסה הודעת ברכה.
3. מחלקות (Classes) ב-JavaScript
ב-ES6 נוספה האפשרות להגדיר מחלקות באמצעות המילה השמורה class
. מחלקה היא תבנית ליצירת אובייקטים. אפשר להגדיר מחלקה פעם אחת ולהשתמש בה שוב ושוב כדי ליצור אובייקטים חדשים.
התחביר של מחלקה:
class ClassName {
constructor(פרמטרים) {
// אתחול מאפיינים
}
methodName() {
// שיטה (method) של המחלקה
}
}
דוגמה ליצירת מחלקה פשוטה:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log("Hello, my name is " + this.name);
}
}
// יצירת מופע חדש של המחלקה
let alice = new Person("Alice", 30);
alice.greet(); // מציג "Hello, my name is Alice"
הסבר:
- המחלקה
Person
היא תבנית שמגדירה איך כל אובייקט שניצור בעזרת המחלקה ייראה. constructor
הוא פונקציה מיוחדת שמופעלת אוטומטית בעת יצירת אובייקט חדש ומאתחלת את המאפיינים.- השיטה
greet
היא פונקציה שמדפיסה הודעת ברכה לפי שם האובייקט.
4. יצירת אובייקטים ממחלקות
מחלקה היא תבנית שממנה ניתן ליצור אובייקטים. כל אובייקט שנוצר ממחלקה נקרא מופע (Instance) של אותה מחלקה.
דוגמה ליצירת מספר מופעים:
let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);
alice.greet(); // מציג "Hello, my name is Alice"
bob.greet(); // מציג "Hello, my name is Bob"
הסבר:
- יצרנו שני מופעים (אובייקטים) מהמחלקה
Person
: האובייקטalice
והאובייקטbob
. - כל אחד מהם משתמש בשיטה
greet
כדי להדפיס הודעה אישית עם השם שלו.
5. הוספת שיטות (Methods) למחלקה
אפשר להוסיף למחלקה שיטות נוספות שיבצעו פעולות נוספות על המאפיינים.
דוגמה להוספת שיטה למחלקה:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log("Hello, my name is " + this.name);
}
celebrateBirthday() {
this.age += 1;
console.log(this.name + " is now " + this.age + " years old!");
}
}
let alice = new Person("Alice", 30);
alice.celebrateBirthday(); // מציג "Alice is now 31 years old!"
הסבר:
- הוספנו למחלקה
Person
שיטה חדשה בשםcelebrateBirthday
שמגדילה את הגיל ב-1 ומדפיסה הודעה חדשה. - כאשר
alice
קוראת לשיטה הזו, הגיל שלה מתעדכן וההודעה מדווחת שהיא בת 31.
6. ירושה (Inheritance)
אחת התכונות החזקות ביותר של תכנות מונחה עצמים היא ירושה. ירושה מאפשרת ליצור מחלקה חדשה שמבוססת על מחלקה קיימת. המחלקה החדשה יורשת את כל המאפיינים והשיטות של המחלקה המקורית, וניתן להוסיף לה מאפיינים ושיטות נוספים.
התחביר של ירושה:
class ChildClass extends ParentClass {
constructor(פרמטרים) {
super(פרמטרים); // קריאה ל-Constructor של המחלקה הבסיסית
// מאפיינים נוספים
}
// שיטות נוספות
}
דוגמה לירושה:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log("Hello, my name is " + this.name);
}
}
// המחלקה Student יורשת מ-Person
class Student extends Person {
constructor(name, age, grade) {
super(name, age); // קריאה ל-Constructor של Person
this.grade = grade;
}
study() {
console.log(this.name + " is studying in grade " + this.grade);
}
}
let student = new Student("Charlie", 20, 10);
student.greet(); // מציג "Hello, my name is Charlie"
student.study(); // מציג "Charlie is studying in grade 10"
הסבר:
- המחלקה
Student
יורשת את המחלקהPerson
באמצעות מילת המפתחextends
. - בתוך ה-
constructor
שלStudent
, אנחנו משתמשים ב-super
כדי לקרוא ל-constructor
של המחלקהPerson
ולאתחל את המאפייניםname
ו-age
. - בנוסף, הוספנו מאפיין חדש (
grade
) ושיטה חדשה (study
) ב-Student
.
7. שימוש ב-getters
ו-setters
ב-JavaScript אפשר להגדיר getters ו-setters למחלקות, כך שניתן לגשת למאפיינים בצורה מסודרת, וגם לבצע בהם שינויים בצורה מבוקרת.
דוגמה לשימוש ב-getters ו-setters:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
// getter לגישה לגיל
get ageInfo() {
return this.name + " is " + this.age + " years old";
}
// setter לעדכון הגיל
set updateAge(newAge) {
if (newAge > 0) {
this.age = newAge;
} else {
console.log("Invalid age");
}
}
}
let alice = new Person("Alice", 30);
console.log(alice.ageInfo); // מציג "Alice is 30 years old"
alice.updateAge = 35;
console.log(alice.ageInfo); // מציג "Alice is 35 years old"
הסבר:
- הגדרנו
get
כדי לקבל מידע על הגיל בצורה מסודרת באמצעותageInfo
. - הגדרנו
set
בשםupdateAge
שמאפשר לעדכן את הגיל תוך ביצוע בדיקה אם הגיל תקין. - כשאנחנו משתמשים ב-getter וב-setter, ניגשים אליהם כמו למאפיין רגיל.
דוגמה מלאה: מערכת ניהול עובדים
נבנה מערכת ניהול פשוטה שמדמה עובדים ותפקידים באמצעות מחלקות וירושה.
class Employee {
constructor(name, position) {
this.name = name;
this.position = position;
}
work() {
console.log(this.name + " is working as a " + this.position);
}
}
class Manager extends Employee {
constructor(name, position, teamSize) {
super(name, position);
this.teamSize = teamSize;
}
manage() {
console.log(this.name + " is managing a team of " + this.teamSize + " employees.");
}
}
let employee = new Employee("John", "Developer");
employee.work(); // מציג "John is working as a Developer"
let manager = new Manager("Alice", "Team Lead", 5);
manager.work(); // מציג "Alice is working as a Team Lead"
manager.manage(); // מציג "Alice is managing a team of 5 employees."
הסבר:
- המחלקה
Employee
מייצגת עובד ומכילה שיטה שמדפיסה את התפקיד שלו. - המחלקה
Manager
יורשת מ-Employee
ומוסיפה שיטה שמציגה כמה עובדים המנהל מנהל. - יצרנו עובד ומנהל והפעלנו את השיטות השונות בהתאם לתפקיד.
סיכום
בפרק זה למדנו על:
- מה זה תכנות מונחה עצמים (OOP) ב-JavaScript וכיצד לעבוד עם אובייקטים.
- איך ליצור מחלקות (
class
) ואובייקטים חדשים באמצעות מחלקות. - הוספת שיטות למחלקות לטובת ביצוע פעולות.
- שימוש בירושה (
inheritance
) כדי ליצור מחלקות חדשות שמבוססות על מחלקות קיימות. - שימוש ב-
getters
ו-setters
לטובת גישה ועדכון מאפיינים באופן מסודר.
בפרק הבא נעמיק בנושא Function Context ונראה כיצד this
מתנהג במצבים שונים ב-JavaScript.