» נושאי לימוד
» נושאי לימוד
יום חמישי 1 במאי 2025
בקרת גישה
דף ראשי  מתחילים  בקרת גישה גרסה להדפסה

בקרת גישה

 

מבוא

סטודנטים בקורס הקדמה לתכנות Java אחראים לידיעת והבנת כל החומר בשעור זה (חוץ מנושאים ספציפיים ב – C++).

הנושאים הספציפיים ב – C++ מוצעים כחומר משלים לטובת אלו שמכירים כבר C++ ומבצעים הסבה ל – Java.

 

הקדמה

 

הן Java והן ++C תומכות במושג של בקרת גישה לחברים אינדיבידואליים במחלקה (משתנים או מתודות).

Java תומכת גם במושג של בקרת גישה למחלקה עצמה.

 

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

המחלקה המורישה מכונה לרוב מחלקת בסיס או מחלקת-על. המחלקה היורשת מכונה לרוב מחלקה נגזרת או תת-מחלקה.

 

כאשר אובייקט נוצר בתת-מחלקה, הוא יכיל את כל החברים במחלקה זו וכמו כן את כל החברים במחלקה המורישה ואת כל החברים באבות הקדמוניים של המחלקה המורישה.

ואולם, ייתכן שהגישה לחברים של אותו אובייקט תהיה מוגבלת על ידי אמצעי בקרת גישה, אשר מיושם על החברים במחלקת-העל של האובייקט.

 

בקרת גישה ב‑Java

 

בקרת גישה ב‑Java היא נושא שתלמידים אחדים מתקשים להבין. קשה גם להסביר אותה בצורה שתהיה מובנת לאדם הפשוט. כל הספרים שברשותי אינם מסבירים את הנושא לשביעות רצוני.

 

אל תסמוך רק על שיעור זה, או כל מקור יחיד אחר, להבנת הנושא. מפאת המורכבות שלו, מומלץ ספרים רבים ככל האפשר כדי להבין אותו מנקודות ראות שונות. במיוחד מומלץ לעיין ב"כללי היסוד" המופיעים בספרו המצוין של David Flanagan   : Java in a Nutshell .

 

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

 

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

 

·       public

·       private

·       protected

·       package (ללא)

 

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

 

שני הראשונים, public ו‑private, הם פשוטים למדי ואינם מהווים מורכבוּת גדולה במיוחד. המורכבות מתגלה ב‑protected וב‑package, בייחוד מבחינת האינטרקציה בין אמצעי גישה אלה לבין ירושה ממחלקות הנמצאות בחבילה אחת, או בחבילות שונות.

 

ב‑Java מוענקות זכויות גישה מיוחדות לחברים באובייקטים אחרים, שנוצרו מתוך מחלקות הנמצאות באותה חבילה, והדבר נעשה תוך שימוש באמצעי הגישה package .

 

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

 

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

 

בטענות הבאות, כאשר מדובר במחלקת-על קולקטיבית, הכוונה לא רק למחלקת-העל הישירה, אלא גם לכל המחלקות במעלֵה היררכיית ההורשה, החל מאותה מחלקה ועד (וכולל) את מחלקת  Object

 

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

בשלב זה של הקורס, עליך להיות מסוגל כבר לכתוב תוכניות משלך כדי לבדוק השערה כלשהי בהקשר של בקרת גישה.

 

נתחיל בכמה טענות לגבי בקרת גישה ברמת המחלקה.

 

גישה למחלקה

 

·       כל קוד, בכל אובייקט, מסוגל לגשת לכל מחלקה, בכל חבילה, וליצור מתוכה אובייקט, אם היא מצוינת באמצעי הגישה public (אלא אם כן היא גם מצוינת באמצעי הגישה abstract, ובמקרה כזה לא ניתן ליצור מתוכה כלל). לגבי מחלקות, לא קיימים אמצעי הגישה private או protected, אלא רק public, abstract ו‑final. אמצעי הגישה abstract ו‑final שוללים זה את זה הדדית.

·       רק הקוד שבתוך החבילה מסוגל לגשת למחלקה שאינה מצוינת באמצעי הגישה public וליצור מתוכה אובייקט (אם המחלקה מצוינת באמצעי הגישה abstract, לא ניתן ליצור מתוכה אובייקטים).

 

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

 

גישה לחברים בתוך המחלקה

 

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

·       בקרת הגישה נאכפת ברמת המחלקה, ולא ברמת האובייקט. זהו היבט חשוב של בקרת גישה, שלרוב לא מוקדש לו דיון מספיק בספרות.

 

גישה לתת-מחלקה

 

·       מנקודת ראותו של אובייקט בתת-מחלקה, המנסֵה לגשת לחברים במחלקת-העל בתוך אותה החבילה, באמצעות עצמו (אובייקט בתת-מחלקה הניגש באמצעות הצבעת this), החברים מסוג public, protected ו‑package הם נגישים. חברים מסוג private אינם נגישים.

·       מנקודת ראותו של אובייקט בתת-מחלקה, המנסֵה לגשת לחברים במחלקת-על שאינה בתוך אותה חבילה, באמצעות עצמו, חברים מסוג public ו‑protected הם נגישים. חברים מסוג private ו‑package אינם נגישים.

 

גישה לחבר private

 

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

 

גישה לחבר public

 

·       כל קוד, בכל אובייקט, מסוגל לגשת לכל החברים מסוג public של כל אובייקט אחר בגבולות הטווח שלו. במילים אחרות, אם הקוד מסוגל לגשת לאובייקט, הוא יוכל גם לגשת לכל החברים מסוג public של אובייקט.

 

גישה לחבר protected

 

·       כל קוד באובייקט שהוא תת-מחלקה של מחלקה אחרת, מסוגל לגשת לכל החברים מסוג protected של מחלקת-העל (הקולקטיבית), ואולם (וזו נקודה חשובה), גישה אוניברסלית כזו מוענקת רק באמצעות אובייקט של תת-המחלקה, ואינה מוענקת בגישה לאובייקט של מחלקת-העל (ראה למטה).

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

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

·       קוד באובייקט של מחלקה מסוגל לגשת לחברים מסוג protected של אובייקט במחלקה אחרת אם אותו אובייקט נמצא בתוך אותה החבילה. כולל חברים המצוינים כ‑protected, שעברו בהורשה לתוך המחלקה האחרת, בתנאי שהם ירשו מתוך מחלקת-על בתוך אותה החבילה.

 

גישה לחבר package

 

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

 

כאמור למעלה, בקרת גישה ל‑public ול‑private אינה כה קשה להבנה. בקרת גישת ל‑package עשויה להיות מסובכת כאשר נוספות עליה דרישות של החבילה ואשר קשורות להורשה.

רוב הבלבול סובב סביב בקרת גישה ל‑protected, והבלבול נובע מכך שההתנהגות משתנה בהתאם לעובדה, אם מדובר בגישה לחברים מסוג protected של מחלקת-על באמצעות:

·       אובייקט של תת-המחלקה, (או)

·       אובייקט של מחלקת-העל.

 

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

 

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

 

למעשה, מרבית התרשימים במרבית הספרים מובילים לרוב למסקנות מוטעות לגבי בקרת הגישה לחברים משני הסוגים הנזכרים, משום שהם אינם מביאים בחשבון, בצורה מניחה את הדעת, חברים מוּרָשים. היות ואין באמת צורך בתרשימים על מנת להסביר את בקרת הגישה ל‑public ול‑private, הרי שרוב התרשימים שיצא לי לראות אינם שימושיים במיוחד. (אני מקווה ששלי יהיה שימושי יותר, אבל על כך תצטרך להחליט אתה.)

 

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

 

על מנת להבין את התרשימים, נניח שישנם שני אובייקטים בשם A ו‑B. הקוד באובייקט A מנסה לגשת לחברים באובייקט B.

החברים באובייקט B עשויים להיות בעלי גישת public, private, protected, או package. החברים באובייקט B עשויים להיות מוגדרים בהגדרת המחלקה, שמתוכה נוצר אובייקט B, או מוּרָשים מתוך מחלקת-על של אותה מחלקה. (והאפשרות האחרונה היא שיוצרת את רוב המורכבות.)

ניסיתי לזהות את רוב הקשרים המעניינים בין אובייקט A לאובייקט B, ולתאר את הנגישות של החברים באובייקט B לקוד באובייקט A.

 

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

 

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

אובייקט B הינו, או איננו, מאותה מחלקה כמו אובייקט A. (כשאני אומר שאובייקט B הוא "מאותה מחלקה", הכוונה היא למעשה "נוצר מתוך אותה מחלקה". הניסוח נועד לשם הפשטות.)

אובייקט B הינו, או איננו, ממחלקה שנמצאת בתוך אותה החבילה שבה גם נמצא אובייקט A.

המחלקה של אובייקט B הינה, או איננה, מחלקת-העל של אובייקט A .

חבר המחלקה שבו מדובר הורש, או שלא הורש, לתוך האובייקט ממחלקת-על.

במידה וחבר המחלקה הורש לתוך האובייקט, הוא חבר במחלקה הנמצאת, או אינה נמצאת, בתוך אותה החבילה כמו האובייקט, שלתוכו הוא הורש.

 

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

 

 29-12-03 / 19:08  נוצר ע"י רונית רייכמן  בתאריך 
 קלט/פלט סטנדרטי - הקודםהבא - protected 
תגובות הקוראים    תגובות  -  0
דרכונט
מהי מערכת הדרכונט?
אינך מחובר, להתחברות:
דוא"ל
ססמא
נושאי לימוד
חיפוש  |  לא פועל
משלנו  |  לא פועל
גולשים מקוונים: 4