מה זה כימוס (Encapsulation)?
בתכנות מונחה עצמים, כימוס (encapsulation) הוא החזקת הנתונים של אובייקט והמתודות שעובדות עליהם יחד ביחידה אחת, בדרך כלל מחלקה, והסתרת הפרטים הפנימיים כך שקוד אחר יוכל להשתמש באובייקט רק דרך המתודות הציבוריות שלו.
עודכן ב-24 בספטמבר 2026
נניח שאפליקציית בנק שומרת את היתרה של כל חשבון במשתנה רגיל. כל שורה בכל מקום בתוכנית יכולה לכתוב account.balance = -500, ושום דבר לא עוצר אותה. כשיתרה שלילית מופיעה בפרודקשן, צריך לחפש בכל בסיס הקוד כל מקום שנגע בה. כימוס פותר את זה: היתרה יכולה להשתנות רק דרך כמה מתודות, והמתודות האלה אוכפות את הכללים, למשל שמשיכה לעולם לא תעלה על היתרה.
איך כימוס עובד
כימוס משלב שני רעיונות:
- איגוד. הנתונים (היתרה) והקוד שעובד עליהם (הפקדה, משיכה) נמצאים באותה מחלקה.
- הסתרה. קוד אחר רואה רק את הממשק הציבורי של המחלקה. הנתונים שמאחוריו פנימיים, ולכן הם יכולים להשתנות רק בדרכים שהמחלקה מתירה.
הכלל שהמחלקה מגינה עליו נקרא אינווריאנט (invariant): כאן, "היתרה אף פעם לא שלילית". מכיוון שכל שינוי עובר דרך המתודות של המחלקה, האינווריאנט מתקיים לא משנה מה שאר התוכנית עושה.
70
refused: not enough money
קוד חיצוני יכול לקרוא את acct.balance, אבל ל-property אין setter, ולכן acct.balance = 1000 זורק AttributeError. אם היתרה אי פעם שגויה, יש בדיוק שתי מתודות לבדוק.
כימוס ב-Python
ב-Python אין מילת מפתח private. היא נשענת על מוסכמות שמות שכל מתכנת Python מכיר:
name: ציבורי, חלק מהממשק._name: פנימי. שום דבר לא מונע מכם לקרוא אותו, אבל הקו התחתון בהתחלה אומר "אל תסתמכו על זה".__name: Python משנה את השם שלו בתוך המחלקה (name mangling), כך שתת מחלקה לא יכולה לדרוס אותו בטעות.@property: הופך מתודה למשהו שנקרא כמו מאפיין, כך שאפשר להוסיף בדיקות מאוחר יותר בלי לשנות שום קוד שקורא לו.
0
False
42
שינוי השם מונע תקלות, לא גישה: השם המשונה עדיין עובד. Python סומכת על המתכנתים שיכבדו את הקו התחתון. בפועל רוב הקוד ב-Python משתמש בקו תחתון אחד יחד עם @property, ושומר קו תחתון כפול למחלקות שנועדו לשמש כמחלקות בסיס. עוד על כתיבת מחלקות תמצאו בתיעוד על מחלקות ב-Python.
כימוס ב-Java, C++ ו-JavaScript
שפות אחרות אוכפות את ההסתרה. ב-Java, אפשר להשתמש בשדה private רק בתוך המחלקה שלו:
public class BankAccount {
private int balance; // hidden from every other class
public int getBalance() { return balance; }
public void withdraw(int amount) {
if (amount > balance) throw new IllegalArgumentException("not enough money");
balance -= amount;
}
}
כתיבת account.balance = 1000; במחלקה אחרת לא עוברת קומפילציה: javac מדווח balance has private access in BankAccount.
| שפה | חבר מוסתר | חבר ציבורי | נאכף על ידי |
|---|---|---|---|
| Python | _name, __name | name | מוסכמה |
| Java | private int name | public int name | הקומפיילר |
| C++ | אזור private: | אזור public: | הקומפיילר |
| JavaScript | #name | name | מנוע ה-JavaScript |
ב-C++ חברי class פרטיים כברירת מחדל וחברי struct ציבוריים. את השדות הפרטיים עם # של JavaScript, שנוספו ב-ES2022, אי אפשר לקרוא מחוץ למחלקה בכלל. התיעוד מכסה כל אחד מהם: מגדירי גישה ב-Java, מגדירי גישה ב-C++ ושדות פרטיים ב-JavaScript.
למה כימוס חשוב
- הכללים נמצאים במקום אחד. הבדיקה "אין משיכה מעל היתרה" נכתבת פעם אחת, בתוך
withdraw, במקום לפני כל משיכה בתוכנית. - אפשר לשנות את הפנים בחופשיות. אם מחליטים לשמור כסף כאגורות שלמות במקום כ-float, רק המחלקה משתנה. קוד שקורא ל-
deposit(100)ממשיך לעבוד. - דיבאגינג קל יותר. כשערך שגוי, החשודות הן כמה המתודות שמורשות לשנות אותו, לא כל שורה בתוכנית.
- פחות מה ללמוד ולבדוק. מחלקה עם שלוש מתודות ציבוריות אפשר להבין ולבדוק דרך שלוש המתודות האלה.
כימוס עובד גם מעל רמת המחלקות. מודול שחושף שתי פונקציות ושומר עשר פונקציות עזר פנימיות מכומס באותה דרך, וכך גם מערכת הפעלה שמאפשרת לתוכניות לפתוח קבצים רק דרך קריאות מערכת.
מבלבלים אותו לעתים קרובות עם אבסטרקציה. אבסטרקציה מחליטה מה הממשק מציע; כימוס מגן על הנתונים שמאחוריו. בעמוד על אבסטרקציה יש השוואה מלאה זה לצד זה. יחד עם פולימורפיזם והורשה, אלה ארבעת עקרונות היסוד של תכנות מונחה עצמים.
טעויות נפוצות
- getter ו-setter לכל שדה.
setBalanceשמקבל כל מספר לא מגן על כלום. הציעו את הפעולות שהאובייקט צריך (withdraw), לא גישה ישירה לכל שדה. - החזרת אובייקטים פנימיים. מתודה שמחזירה
self._itemsמוסרת לקורא את הרשימה האמיתית, שעכשיו הוא יכול לשנות. החזירו עותק או tuple במקום. - התייחסות ל-private כאל אבטחה. מגדירי גישה מונעים טעויות, לא מתקפות. קוד Java יכול לקרוא שדות פרטיים דרך reflection, וקוד Python יכול לקרוא
_nameישירות. סיסמאות ומפתחות צריכים הגנה אמיתית, כמו גיבוב והצפנה.
לאן ממשיכים מכאן
קראו עכשיו את העמוד על אבסטרקציה, שמסביר את ההבדל בין שני הרעיונות, ואז על פולימורפיזם. קורס Python בונה מחלקות צעד אחרי צעד, וקורס Java מראה כימוס שנאכף על ידי הקומפיילר.
שאלות נפוצות
מה זה כימוס במילים פשוטות?
deposit ו-withdraw, שבודקות קודם את הכללים. השם באנגלית בא מקפסולה, מעטפת ששומרת את התוכן שלה בפנים.מהן דוגמאות לכימוס?
deposit ו-withdraw היא הדוגמה הקלאסית. ה-list של Python עצמה היא דוגמה נוספת: קוראים ל-append ואף פעם לא מנהלים את הזיכרון ששומר את הפריטים. מודול שחושף כמה פונקציות ושומר את פונקציות העזר שלו פרטיות הוא כימוס בקנה מידה גדול יותר.מהם שלושת סוגי הכימוס?
מה זה כימוס ב-C++ ואיך משתמשים בו?
private ומספקים פונקציות חברות public שקוראות או משנות אותם. חברים של class הם פרטיים כברירת מחדל, ואילו חברים של struct הם ציבוריים כברירת מחדל. הקומפיילר דוחה כל קוד מחוץ למחלקה שמנסה להשתמש בחבר פרטי.