Menu

Java Access Modifiers: public, private, protected ו-default

איך ארבע רמות הגישה של Java, public, private, protected ו-package-private, קובעות מה קוד אחר יכול לראות ולשנות.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

מי רשאי לגעת בקוד שלכם

access modifier היא מילת מפתח שמופיעה לפני מחלקה, שדה, מתודה או בנאי, וקובעת מי עוד רשאי להשתמש בהם. זה הבסיס של אנקפסולציה: מסתירים את הפרטים הפנימיים המבולגנים של מחלקה וחושפים רק את החלקים שסומכים על קוד אחר שיקרא להם.

ל-Java יש ארבע רמות, מהפתוחה ביותר לנעולה ביותר: public, protected, default (בלי מילת מפתח בכלל) ו-private. אם בוחרים אותן נכון, בטוח לשנות את המחלקה בהמשך, כי שום דבר מחוצה לה לא תלוי בפרטים שמעולם לא הבטחתם לשמור.

private: גלוי רק בתוך המחלקה

private היא הרמה ההדוקה ביותר. לחבר private יכול לגשת רק קוד שנכתב בתוך אותה מחלקה: לא תתי-מחלקות, לא מחלקות אחרות באותה חבילה, אף אחד. כאן המקום של רוב השדות שלכם.

balance הוא private, ולכן הדרך היחידה לשנות אותו היא דרך deposit, שדוחה סכומים שליליים. אם balance היה public, כל קוד היה יכול לכתוב account.balance = -9999 ולדלג על הבדיקה לגמרי. הבדיקה הזו היא כל הטעם בהסתרת השדה.

נסו להוסיף את השורה account.balance = 500; ב-main ותקבלו שגיאת קומפילציה: balance has private access in BankAccount.

public: גלוי בכל מקום

public הוא הקצה ההפוך: כל אחד, מכל מקום, יכול להשתמש בחבר. מתודות שנועדו להיקרא מקוד אחר הן בדרך כלל public. כך גם המחלקה עצמה, כשצריך להגיע אליה מחבילות אחרות.

הדפוס הנפוץ, שלפעמים נקרא ה-public API של מחלקה, הוא שדות private, מתודות public. השדות מחזיקים מצב שאף אחד אחר לא אמור לשחק בו; המתודות הן הדלתות המבוקרות פנימה והחוצה. getBalance ו-deposit שראינו קודם הן בדיוק זה.

default (Package-Private): בלי מילת מפתח בכלל

אם לא כותבים שום modifier, מקבלים גישת default, שנקראת גם package-private. החבר גלוי לכל מחלקה באותה חבילה ובלתי נראה לכל מה שמחוצה לה. אין מילת מפתח לרמה הזו: ההיעדר של מילת מפתח הוא הרמה.

class Invoice {       // בלי modifier -> גלוי רק בתוך החבילה הזו
    int amount;       // בלי modifier -> שדה package-private
}

זה מפיל הרבה מתחילים: השמטה של public לא הופכת משהו ל-private, היא הופכת אותו ל-package-private. שדה שהתכוונתם לשמור בסוד עדיין ניתן לקריאה ולכתיבה מלאות מכל מחלקה שנמצאת באותה חבילה. אם רוצים שהוא יהיה מוסתר באמת, חייבים לכתוב private במפורש.

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

protected: החבילה וגם תתי-מחלקות

protected מקלה בדרגה אחת יותר מ-default. חבר protected גלוי בכל מקום שבו default גלוי (אותה חבילה), וגם לתתי-מחלקות, אפילו לתתי-מחלקות בחבילה אחרת. היא נועדה לדברים שרוצים לשתף עם מחלקות שמרחיבות את שלכם, אבל לא עם כל העולם.

Dog ניגשת ל-name ול-sound() כי הם protected ו-Dog היא תת-מחלקה. קוד חיצוני שאינו תת-מחלקה ואינו בחבילה עדיין לא יכול לגעת בהם. בחרו ב-protected כשאתם מתכננים מחלקה שנועדה להרחבה; אחרת העדיפו private.

ארבע הרמות במבט אחד

הנה התמונה המלאה, מהמגבילה ביותר לפתוחה ביותר:

Modifierאותה מחלקהאותה חבילהתת-מחלקה (חבילה אחרת)בכל מקום
privateכןלאלאלא
defaultכןכןלאלא
protectedכןכןכןלא
publicכןכןכןכן

כלל אצבע פשוט: התחילו עם private והרחיבו רק כשמשהו באמת צריך גישה רחבה יותר. הרבה יותר קל להרחיב גישה בהמשך מאשר לצמצם אותה אחרי שקוד אחר כבר התחיל להסתמך על חבר.

Modifiers על מחלקות עצמן

access modifiers חלים גם על מחלקות, לא רק על חברים, אבל מחלקה עליונה (כזו שאינה מקוננת בתוך מחלקה אחרת) יכולה להיות רק public או default. אי אפשר לכתוב מחלקה עליונה private או protected.

public class Order { ... }   // נגישה מכל חבילה
class LineItem { ... }       // default: רק החבילה הזו רואה אותה

מחלקה עליונה public חייבת להיות בקובץ שנקרא על שמה (Order.java). לעומת זאת, מחלקות מקוננות יכולות להשתמש בכל ארבעת ה-modifiers, ולכן בדוגמאות הקודמות אפשר היה לסמן מחלקות פנימיות כ-private או default. נקודה עדינה: מתודה public שמחזירה טיפוס package-private לא שימושית במיוחד לקוראים מבחוץ, אז שמרו על ממשק ציבורי עקבי.

הבא בתור: חברים סטטיים

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

שאלות נפוצות

מהם ארבעת ה-access modifiers ב-Java?

public, private, protected וברירת המחדל (בלי מילת מפתח, נקראת גם package-private). public גלוי בכל מקום, private רק בתוך אותה מחלקה, protected בתוך החבילה וגם בתתי-מחלקות, וברירת המחדל רק בתוך אותה חבילה.

מה ההבדל בין public ל-private ב-Java?

public אומר שכל קוד, מכל מקום, יכול לגשת לחבר. private אומר שרק קוד בתוך אותה מחלקה יכול: תתי-מחלקות ומחלקות אחרות אפילו לא רואות אותו. בדרך כלל הופכים שדות ל-private וחושפים אותם דרך מתודות public.

מה המשמעות כששדה ב-Java הוא בלי access modifier?

בלי מילת מפתח מקבלים גישת ברירת מחדל (package-private): החבר גלוי לכל מחלקה באותה חבילה, אבל בלתי נראה מחוץ לה. זה מחמיר יותר מ-public אבל מקל יותר מ-private, וקל לשכוח את המילה בטעות, אז כדאי לעשות את זה בכוונה.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל