Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

منصة التعليم الإلكتروني

جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 84 من 87.

مرحباً بك في فصل التحديات النهائية! تم تصميم هذه التحديات لاختبار إتقانك لجميع مفاهيم OOP التي تعلمتها طوال هذه الدورة.

في هذا التحدي، ستقوم ببناء نظام منصة تعليم إلكتروني يجمع بين الوراثة (inheritance)، والواجهات (interfaces)، وتعدد الأشكال (polymorphism)، والتغليف (encapsulation)، وأنماط التصميم (design patterns) في تطبيق متماسك.

يجب أن تقوم منصتك بنمذجة العلاقات بين الدورات والطلاب والمدربين. فكر في كيفية توسيع الفئة الأساسية User بواسطة فئتي Student و Instructor، وكيف تحتوي الدورات على دروس، وكيف يعمل تتبع الالتحاق بين الطلاب والدورات.

فكر في أي من مبادئ البرمجة كائنية التوجه (OOP) تنطبق: استخدم التغليف (encapsulation) لحماية بيانات المستخدم، والوراثة (inheritance) لمشاركة السلوك المشترك، والواجهات (interfaces) لتحديد العقود مثل Enrollable أو Completable، وتعدد الأشكال (polymorphism) للتعامل مع أنواع المستخدمين المختلفة بشكل موحد.

بالتوفيق في تطبيق كل ما تعلمته!

challenge icon

التحدي

سهل

لنقم ببناء منصة للتعلم الإلكتروني تجمع بين جميع مفاهيم البرمجة كائنية التوجه (OOP) التي أتقنتها طوال هذه الدورة! ستقوم بإنشاء نظام ينمذج العلاقات بين الدورات التدريبية والطلاب والمدربين باستخدام الوراثة، والواجهات (interfaces)، وتعدد الأشكال (polymorphism)، والتغليف (encapsulation).

ستقوم بتنظيم الكود الخاص بك عبر ستة ملفات:

  • Enrollable.java: أنشئ واجهة (interface) تحدد العقد لعمليات التسجيل. يجب أن تعلن عن الأساليب enroll(Student student) التي تعيد قيمة منطقية (boolean)، و getEnrolledCount() التي تعيد قيمة صحيحة (int).
  • User.java: أنشئ فئة أساسية مجردة (abstract base class) تمثل أي مستخدم على المنصة. قم بتضمين حقول خاصة (private) لـ id (String) و name (String)، ومنشئ (constructor) يقوم بتهيئة كليهما، وجلب البيانات (getters) المناسبة، وطريقة مجردة getRole() تعيد String يصف دور المستخدم.
  • Student.java: أنشئ فئة ترث من User. أضف ArrayList خاصًا لتتبع معرفات الدورات المسجل فيها. قم بتضمين منشئ يستدعي منشئ الفئة الأب، وقم بتنفيذ getRole() لتعيد "Student"، وأضف الأساليب addCourse(String courseId) و getEnrolledCourseCount(). قم بإعادة تعريف (Override) لـ toString() لتعيد "Student: [name] ([enrolledCount] courses)".
  • Instructor.java: أنشئ فئة ترث من User. أضف حقلًا خاصًا لـ specialty (String). قم بتضمين منشئ يأخذ id و name و specialty، وقم بتنفيذ getRole() لتعيد "Instructor"، وأضف getter للتخصص، وقم بإعادة تعريف toString() لتعيد "Instructor: [name] - [specialty]".
  • Course.java: أنشئ فئة تنفذ الواجهة Enrollable. قم بتضمين حقول خاصة لـ courseId (String)، و title (String)، و instructor (Instructor)، و ArrayList من الطلاب المسجلين. يأخذ المنشئ courseId و title و instructor. قم بتنفيذ enroll(Student student) لإضافة الطالب إلى القائمة، واستدعاء أسلوب addCourse() الخاص بالطالب مع معرف هذه الدورة، وإرجاع true. قم بتنفيذ getEnrolledCount(). أضف أسلوب getDetails() الذي يعيد "[courseId] [title] by [instructorName]".
  • Main.java: ابنِ منصتك! ستتلقى سلسلة نصية من الأوامر مفصولة بفاصلة:
    • ADD_INSTRUCTOR:id:name:specialty
    • ADD_STUDENT:id:name
    • ADD_COURSE:courseId:title:instructorId
    • ENROLL:studentId:courseId
    • INFO:userId

    حافظ على مجموعات من المدربين والطلاب والدورات. قم بمعالجة كل أمر واطبع:

    • ADD_INSTRUCTOR: Instructor added: [name]
    • ADD_STUDENT: Student added: [name]
    • ADD_COURSE: Course added: [title]
    • ENROLL: [studentName] enrolled in [courseTitle]
    • INFO: اطبع مخرجات toString() الخاصة بالمستخدم

    بعد كل الأوامر، اطبع --- Platform Summary --- متبوعًا بتفاصيل كل دورة وعدد المسجلين فيها بالتنسيق [courseDetails] - [count] student(s).

ستتلقى مدخلاً واحدًا: سلسلة أوامر مفصولة بفاصلة.

على سبيل المثال، مع المدخلات ADD_INSTRUCTOR:I001:Dr. Smith:Java,ADD_STUDENT:S001:Alice,ADD_STUDENT:S002:Bob,ADD_COURSE:C001:OOP Fundamentals:I001,ENROLL:S001:C001,ENROLL:S002:C001,INFO:S001,INFO:I001، ستكون مخرجاتك:

Instructor added: Dr. Smith
Student added: Alice
Student added: Bob
Course added: OOP Fundamentals
Alice enrolled in OOP Fundamentals
Bob enrolled in OOP Fundamentals
Student: Alice (1 courses)
Instructor: Dr. Smith - Java
--- Platform Summary ---
[C001] OOP Fundamentals by Dr. Smith - 2 student(s)

يجمع هذا التحدي بين الوراثة (تسلسل User الهرمي)، والواجهات (Enrollable)، وتعدد الأشكال (أنواع مستخدمين مختلفة مع تنفيذ toString الخاص بها)، والتغليف (حقول خاصة مع وصول متحكم فيه) في نظام متماسك!

ورقة مرجعية

يجمع هذا التحدي النهائي بين مفاهيم متعددة للبرمجة كائنية التوجه (OOP) في نظام متماسك:

الواجهات (Interfaces)

تحديد العقود للسلوك الذي يجب على الفئات (classes) تنفيذه:

public interface Enrollable {
    boolean enroll(Student student);
    int getEnrolledCount();
}

الفئات المجردة (Abstract Classes)

إنشاء فئات أساسية بسلوك مشترك وطرق (methods) مجردة:

public abstract class User {
    private String id;
    private String name;
    
    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public abstract String getRole();
}

الوراثة (Inheritance)

توسيع الفئات الأساسية لإنشاء أنواع متخصصة:

public class Student extends User {
    private ArrayList<String> enrolledCourses;
    
    public Student(String id, String name) {
        super(id, name);
        this.enrolledCourses = new ArrayList<>();
    }
    
    @Override
    public String getRole() {
        return "Student";
    }
}

تنفيذ الواجهات (Implementing Interfaces)

يمكن للفئات تنفيذ الواجهات للوفاء بالعقود:

public class Course implements Enrollable {
    private ArrayList<Student> enrolledStudents;
    
    @Override
    public boolean enroll(Student student) {
        enrolledStudents.add(student);
        student.addCourse(courseId);
        return true;
    }
    
    @Override
    public int getEnrolledCount() {
        return enrolledStudents.size();
    }
}

تعدد الأشكال (Polymorphism)

يمكن للفئات المختلفة تجاوز الطرق (methods) لتوفير سلوك متخصص:

@Override
public String toString() {
    return "Student: " + name + " (" + enrolledCourses.size() + " courses)";
}

التغليف (Encapsulation)

استخدم الحقول الخاصة (private fields) مع وصول محكوم من خلال الطرق (methods) لحماية سلامة البيانات والحفاظ على العلاقات بين الكائنات.

جرّب بنفسك

import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: إنشاء مجموعات لتخزين المعلمين، والطلاب، والدورات التدريبية
        // Hint: استخدم HashMap مع id كمفتاح لسهولة البحث
        
        // TODO: تقسيم المدخلات بواسطة الفاصلة للحصول على الأوامر الفردية
        
        // TODO: معالجة كل أمر:
        // - ADD_INSTRUCTOR:id:name:specialty -> إنشاء معلم، وإضافته إلى المجموعة، وطباعة "Instructor added: [name]"
        // - ADD_STUDENT:id:name -> إنشاء طالب، وإضافته إلى المجموعة، وطباعة "Student added: [name]"
        // - ADD_COURSE:courseId:title:instructorId -> إنشاء دورة تدريبية مع معلم، وإضافتها إلى المجموعة، وطباعة "Course added: [title]"
        // - ENROLL:studentId:courseId -> تسجيل طالب في دورة تدريبية، وطباعة "[studentName] enrolled in [courseTitle]"
        // - INFO:userId -> البحث عن مستخدم (طالب أو معلم) وطباعة toString() الخاصة به
        
        // TODO: بعد معالجة جميع الأوامر، اطبع "--- Platform Summary ---"
        
        // TODO: لكل دورة تدريبية، اطبع "[courseDetails] - [count] student(s)"
    }
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming