על ידי ציון שיטת מחלקה עם משנה
final
, אנו מתכוונים לכך שאף מחלקה נגזרת לא מסוגלת לעקוף את השיטה הזו על ידי שינוי היישום הפנימי שלה. במילים אחרות, אנחנו מדברים על הגרסה הסופית של השיטה. ניתן לסמן את הכיתה כולה גם כ final
.
final class NoExtending {
// …
}
מחלקה המסומנת בתור final
אינה ניתנת בירושה וכל השיטות שלה רוכשות בעקיפין את הנכס final
. שימוש בתכונה a final
בהצהרות על מחלקות ושיטות יכול להגביר את רמת אבטחת הקוד. אם מחלקה מצוידת ב-modifier final
, אף אחד לא יכול להאריך את המחלקה וכנראה להפר את החוזה שלה בתהליך. אם שלט final
מציין שיטה, אתה יכול לסמוך על היישום הפנימי שלה בכל המצבים ללא חשש מ"זיוף". ראוי להשתמש final
, למשל, בהצהרה על שיטה הדורשת אימות של הסיסמה שהוזנה על ידי המשתמש כדי להבטיח את הביצוע המדויק של מה שהתכוונה השיטה במקור. תוקף אפשרי לא יוכל לשנות את ההטמעה המקורית של שיטה כזו על ידי "החלקה" לתוכנית של גרסה עוקפת שלה, אשר, נניח, תמיד מחזירה את הערך true, המצביע על רישום מוצלח של המשתמש, ללא קשר למה סיסמה שהוא הזין בפועל. יש לך את הזכות, אם המצב הספציפי מאפשר, ללכת רחוק יותר ולהכריז על final
כל הכיתה ככיתה; השיטה ValidatePassword
תרכוש את אותו נכס בעקיפין. השימוש ב-modifier final
בהצהרת שיטה או מחלקה מטיל הגבלות חמורות על האפשרות להמשך שימוש ופיתוח של הקוד. השימוש final
בשיטה בהצהרה הוא אינדיקטור בטוח לכך שהטמעת השיטה היא עצמאית ומושלם לחלוטין. מתכנתים אחרים שרוצים להשתמש בכיתה שלך, להרחיב את הפונקציות שלה כך שיתאימו לצרכים שלהם, יהיו מוגבלים בבחירת האמצעים להשגת מטרתם או יישלל מהם לחלוטין. על ידי סימון final
מחלקה כמכלול, תשבית את יכולתה לעבור בירושה וככל הנראה תפחית משמעותית את התועלת שלה לאחרים. כאשר אתה עומד להשתמש במשנה final
, ודא אם אתה מוכן לקורבנות כאלה והאם כדאי לעשות אותם. במקרים רבים, כדי להשיג רמה מספקת של אבטחת קוד, אין צורך לייעד את המחלקה כולה בתור final
- ניתן בהחלט לשמר את יכולת ההרחבה של המחלקה על ידי סימון final
רק האלמנטים המבניים ה"קריטיים" שלה ב-modifier. במקרה זה, תשאיר את הפונקציות העיקריות של המחלקה על כנו ובמקביל תאפשר את הירושה שלה עם הוספת חברים חדשים, אך מבלי להגדיר מחדש את ה"ישנים". כמובן, השדות אליהם ניגש הקוד של המתודות final
חייבים להיות מוגדרים כאחד final
, private
מכיוון שאם לא כן, כל מחלקה נגזרת תוכל לשנות את תוכנם, ולהשפיע על ההתנהגות של השיטות המתאימות. אפקט נוסף של שימוש במשנה final
קשור לפישוט בעיית אופטימיזציית הקוד שנפתרה על ידי המהדר. זה מה שקורה כששיטה שלא מסומנת כמו נקראתfinal
, מערכת זמן הריצה קובעת את המחלקה האמיתית של האובייקט, משייכת את הקריאה לקוד המתאים ביותר מקבוצת השיטות העמוסות, ומעבירה שליטה לקוד זה. אבל אם, למשל, השיטה getName
בדוגמה של המחלקה Attr
שנדונה קודם לכן הייתה מוגדרת כ- final
, פעולת הקריאה לה עשויה להיות מפושטת בצורה ניכרת. במקרה הטריוויאלי ביותר, כמו זה הנוגע getName
, המהדר יכול פשוט להחליף את קריאת השיטה בקוד הגוף שלו. מנגנון זה נקרא קוד מוטבע. בעת שימוש בגרסה המוטבעת של השיטה, getName
שני הביטויים הבאים מבוצעים בדיוק זהה:
system.out.println("id = " + rose.name);
system.out.println("id = " + rose.getName());
למרות שהביטויים שלעיל שווים, לשני עדיין יש יתרון, שכן השיטה getName
מאפשרת לתת לשדה השם תכונה לקריאה בלבד, ולקוד המחלקה יש מידה מסוימת של הפשטה, המאפשרת לך לשנות בצורה חופשית יותר את יישום בכיתה. ניתן להחיל את אותה סכימת אופטימיזציה על ידי המהדר על שיטות private
ו statiс
, מכיוון שהן גם אינן מאפשרות דריסה. שימוש במשנה final
בהצהרות מחלקות גם הופך פעולות מסוימות לבדיקת סוגים ליעילות יותר. במקרה זה, פעולות רבות כאלה יכולות להתבצע כבר בשלב ההידור ולכן שגיאות פוטנציאליות מתגלות הרבה יותר מוקדם. אם המהדר נתקל בהפניה למחלקה בטקסט המקור final
, זה יכול להיות "בטוח" שהאובייקט המתאים הוא מהסוג שצוין. המהדר מסוגל לקבוע מיד את המקום שתופס מחלקה בהיררכיית המחלקות הכללית ולבדוק האם נעשה בה שימוש נכון או לא. אם השינוי final
אינו מוחל, הבדיקות המתאימות מבוצעות רק בשלב ביצוע התוכנית. תרגיל 3.4. האם מומלץ לכלול את השינוי הסופי בהצהרות השיטה (ואם כן, אילו) של מחלקות הרכב ורכב הנוסעים ? קישור למקור המקורי: http://src-code.net/metody-i-klassy-final-java
GO TO FULL VERSION