Menu
Coddy logo textTech

מילת המפתח final

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 13 מתוך 87.

מילת המפתח final ב-Java מונעת שינוי. אפשר להחיל אותה על משתנים, מתודות ומחלקות, ולכל אחד מהם יש השפעה שונה.

כאשר מחילים את משתנה, final הופך אותו לקבוע — לאחר שהוקצה לו ערך, אי אפשר לשנות את ערכו:

public class Circle {
    private final double PI = 3.14159;
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;  // אפשר להקצות ערך פעם אחת בבנאי
    }
    
    public void setRadius(double r) {
        // this.radius = r;  // שגיאה! אי אפשר להקצות מחדש ערך למשתנה final
    }
}

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

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

private final StringBuilder name = new StringBuilder("John");

// name = new StringBuilder("Jane");  // שגיאה! אי אפשר להציב ערך מחדש
name.append(" Doe");  // תקין! אפשר לשנות את תוכן האובייקט

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

challenge icon

אתגר

קל

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

תיצרו שני קבצים כדי לארגן את הקוד:

  • Student.java: צרו מחלקה בשם Student שבה מידע מסוים ננעל לצמיתות לאחר הגדרתו:
    • שדה final בשם studentId (String) — נקבע בעת היצירה ואי אפשר לשנות אותו לעולם
    • שדה final בשם enrollmentYear (int) — שנת הרישום של התלמיד, שגם היא קבועה
    • שדה פרטי רגיל בשם name (String) — אפשר לעדכן אותו אם התלמיד משנה את שמו
    • בנאי שמקבל את שלושת הערכים ומאתחל את השדות
    • getter בשם getStudentId() עבור מזהה התלמיד
    • getter בשם getEnrollmentYear() עבור שנת הרישום
    • getter בשם getName() ו-setter בשם setName() עבור השם
    • מתודה בשם getInfo() שמחזירה: "ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
  • Main.java: צרו אובייקט Student, לאחר מכן עדכנו את שמו והציגו את המידע שלו. תקבלו ארבעה קלטים: מזהה התלמיד, השם ההתחלתי, שנת הרישום ושם חדש לעדכון. הדפיסו שתי שורות:
    • מידע על התלמיד לפני שינוי השם
    • מידע על התלמיד אחרי שינוי השם

תקבלו ארבעה קלטים לפי הסדר: studentId (String), name (String), enrollmentYear (int) ו-newName (String).

שימו לב כיצד השדות final מגינים על מזהה התלמיד ועל שנת הרישום שלו — אלה רשומות קבועות שאסור לשנות, בעוד שאפשר לעדכן את השם באמצעות ה-setter שלו.

נסו בעצמכם

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // קרא את הקלטים
        String studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // צרוך את תו השורה החדשה
        String newName = scanner.nextLine();
        
        // TODO: צור אובייקט Student עם הערכים ההתחלתיים
        
        // TODO: הדפס את פרטי התלמיד לפני שינוי השם
        
        // TODO: עדכן את שם התלמיד באמצעות ה-setter
        
        // TODO: הדפס את פרטי התלמיד אחרי שינוי השם
    }
}
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Java אונליין