Menu
CoddyTech

الكلمة المفتاحية 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 مع الحقول المقصود بوضوح؛ فهو يخبر المطورين الآخرين بأن هذه القيمة يجب ألا تتغير أبدًا بعد تهيئتها. وهذا مفيد خصوصًا لقيم الإعدادات أو المعرّفات أو أي بيانات يجب أن تظل ثابتة طوال عمر الكائن.

لا يمكن إعادة تعريف final طريقة في فئة فرعية:

class Base {
    public final void greet() {
        System.out.println("Hi");
    }
}
class Child extends Base {
    // public void greet() { }  // خطأ! greet() نهائية في Base
}

لا يمكن توسيع صنف final على الإطلاق. ‏String صنف نهائي، لذا لا يمكن لأي صنف أن يرثه:

final class Config { }
// class MyConfig extends Config { }  // خطأ! Config هي 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: حدّث اسم الطالب باستخدام دالة الضبط
        
        // TODO: اطبع معلومات الطالب بعد تغيير الاسم
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Java عبر الإنترنت