شرح مادة CPCS 203 برمجة 2 - جامعة الملك عبدالعزيز

فريق زدني فريق زدني 15 فبراير 2026
6 دقائق للقراءة
شرح مادة CPCS 203 برمجة 2 - جامعة الملك عبدالعزيز

مادة CPCS 203، برمجة 2 / البرمجة كائنية التوجه (Object-Oriented Programming). هي المادة اللي تنقلك من مرحلة “أكتب كود يشتغل” إلى مرحلة “أصمم برنامج منظم وقابل للتطوير”. في خطة قسم علوم الحاسب بجامعة الملك عبدالعزيز، هذه المادة تبني على ما تعلمته في CPCS 202 (برمجة 1) وتجهّزك لمواد مثل هياكل البيانات، هندسة البرمجيات، وقواعد البيانات.

كثير من الطلاب يحسون إن OOP مجرد “كلاسات وأوبجكتات”. لكن الحقيقة إنها طريقة تفكير كاملة في تصميم البرامج. كل مشروع حقيقي في سوق العمل، تطبيقات الجوال، المواقع، الأنظمة، مبني على مبادئ OOP. لو فهمتها صح، راح تقدر تقرأ وتكتب أي كود بثقة.

📋 ملخص سريع

  • رمز المادة: CPCS 203، برمجة 2 / البرمجة كائنية التوجه (Programming II / OOP)
  • الساعات المعتمدة: 3 ساعات (3 نظري + 1 لاب عملي)
  • المتطلب السابق: CPCS 202 (برمجة 1)
  • اللغة المستخدمة: Java
  • الكتاب المقرر:Introduction to Java Programming, Comprehensive”، Y. Daniel Liang (الفصول المتقدمة)
  • الواجبات: واجبان (2) خلال الفصل - برمجة عملية لا نظرية
  • اختبار اللاب النهائي: تحل برنامج كامل في اللاب (مثل الواجب تماما)
  • يقود إلى: CPCS 204 (هياكل البيانات 1) ومواد هندسة البرمجيات وقواعد البيانات

ليش مادة CPCS 203 مهمة؟

  • كل شيء بعدها مبني على OOP: هياكل البيانات، هندسة البرمجيات، تطوير الويب، كلها تفترض إنك تفهم OOP
  • المشاريع الكبيرة مستحيلة بدونها: تخيّل تكتب نظام إدارة مستشفى كله في main واحد، مستحيل. OOP تعلّمك تقسّم المشكلة
  • المقابلات الوظيفية: شركات كثيرة تسأل عن مبادئ OOP في المقابلات
  • أساس التصميم الجيد: مبادئ مثل SOLID مبنية على OOP

نظرة عامة على مادة CPCS 203

المادة تتوزع على 15 أسبوع تقريبا:

الأسابيعالموضوعالمفاهيم الرئيسية
1-2مراجعة أساسيات + مقدمة في الكلاساتclass, object, constructor
3-4الكلاسات والكائنات بالتفصيلattributes, methods, this keyword
5-6التغليف (Encapsulation)private/public, getters/setters
7-8الوراثة (Inheritance)extends, super, method overriding
9-10تعدد الأشكال (Polymorphism)overloading, overriding, dynamic binding
11التجريد والواجهاتabstract classes, interfaces
12-13معالجة الاستثناءات + ملفات I/Otry/catch, File, Scanner, PrintWriter
14مصفوفات الكائناتArrayList, arrays of objects
15مراجعة + اختبار اللاب النهائيحل برنامج كامل في اللاب

ℹ️ عن الكتاب المقرر

المادة تستخدم نفس كتاب Liang من CPCS 202 لكن الفصول المتقدمة (عادة من Chapter 9 وما بعده). لو عندك الكتاب من المادة السابقة، ما تحتاج تشتري كتاب جديد.

1. الكلاسات والكائنات، Classes & Objects

هذا الأساس. كل شيء في OOP يدور حوله.

Class = القالب (مثل مخطط بيت) Object = النسخة الفعلية (مثل البيت نفسه)

public class Student {
    String name;
    int id;
    double gpa;

    public Student(String name, int id, double gpa) {
        this.name = name; // this = الكائن الحالي
        this.id = id;
        this.gpa = gpa;
    }

    public void displayInfo() {
        System.out.println(name + " | " + id + " | GPA: " + gpa);
    }

    public boolean isHonors() { return gpa >= 4.5; }
}

الكلاس فيه: خصائص (attributes)، منشئ (constructor)، ودوال (methods). الحين ننشئ كائنات منه:

Student s1 = new Student("أحمد", 1234567, 4.8);
Student s2 = new Student("سارة", 7654321, 3.9);

s1.displayInfo();              // أحمد | 1234567 | GPA: 4.8
System.out.println(s1.isHonors()); // true
System.out.println(s2.isHonors()); // false

الكلمة المفتاحية this

this تشير للكائن الحالي. تستخدمها عادة لما اسم الـ parameter نفس اسم الـ attribute:

public Student(String name, int id) {
    this.name = name;  // this.name = attribute الكلاس، name = parameter المنشئ
    this.id = id;
}

💡 نصيحة مهمة

دائما سمّي متغيرات الكلاس بأسماء واضحة ومعبرة. name أفضل من n، و studentGpa أفضل من g. الكود الواضح يسهّل عليك المراجعة ويعطيك درجات أفضل في المشاريع.

2. التغليف، Encapsulation

التغليف يعني إنك تحمي بيانات الكائن من الوصول المباشر. تخلي المتغيرات private وتوفّر دوال getter و setter للوصول لها.

ليش؟ عشان تتحكم في القيم وتمنع الأخطاء. مثلا: المعدل لازم يكون بين 0 و 5، بدون تغليف أي شخص يقدر يحط قيمة خاطئة.

public class Student {
    private String name; // private = لا وصول مباشر
    private double gpa;

    public Student(String name, double gpa) {
        this.name = name;
        setGpa(gpa); // نستخدم setter للتحقق
    }

    public String getName() { return name; }       // getter
    public double getGpa() { return gpa; }         // getter

الـ Setter هو المكان اللي نتحكم فيه بالقيم. مثلا نمنع أي معدل خارج 0-5:

    public void setGpa(double gpa) {
        if (gpa >= 0 && gpa <= 5.0)
            this.gpa = gpa;
        else
            System.out.println("خطأ: المعدل لازم بين 0 و 5");
    }
}
Student s = new Student("محمد", 4.2);
System.out.println(s.getName()); // محمد
s.setGpa(6.0);  // خطأ: المعدل لازم بين 0 و 5
s.setGpa(4.5);  // تمام
// s.name = "علي"; // خطأ! name هي private

⚠️ خطأ شائع في الاختبار

كثير من الطلاب ينسون يخلون المتغيرات private ويكتبون getters/setters لمتغيرات public. هذا ما يعتبر تغليف حقيقي. التغليف = private attributes + public getters/setters.

أكثر خطأ يجي في واجبات التغليف: الطالب يكتب الـ getter والـ setter صح، لكن ينسى يحوّل المتغير لـ private. الكود يشتغل بشكل طبيعي — بس درجة التغليف صفر لأن الـ attribute مازال public.

الوراثة من أكثر المواضيع اللي الطلاب يحتاجون وقت عشان يفهمونها صح. خذ وقتك وركّز على الأمثلة العملية.

3. الوراثة، Inheritance

عندك كلاس فيه خصائص مشتركة مع كلاس ثاني؟ بدل ما تكرر الكود، تستخدم الوراثة.

الفكرة: كلاس ابن (subclass) يرث خصائص ودوال كلاس أب (superclass).

public class Person {
    protected String name;
    protected int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("اسمي " + name + " وعمري " + age);
    }
}

الكلاس Student يرث من Person باستخدام extends، ويضيف خصائصه الخاصة:

public class Student extends Person {
    private int studentId;

    public Student(String name, int age, int studentId) {
        super(name, age); // استدعاء منشئ الأب
        this.studentId = studentId;
    }

    @Override
    public void introduce() {
        super.introduce(); // النسخة الأصلية أولا
        System.out.println("رقمي الجامعي: " + studentId);
    }
}

نفس الفكرة مع كلاس الموظف:

public class Employee extends Person {
    private String dept;

    public Employee(String name, int age, String dept) {
        super(name, age);
        this.dept = dept;
    }

    @Override
    public void introduce() {
        super.introduce();
        System.out.println("قسم: " + dept);
    }
}

مفاهيم مهمة في الوراثة

  • extends: الكلمة المفتاحية للوراثة
  • super(): لاستدعاء منشئ الكلاس الأب، لازم يكون أول سطر في المنشئ
  • @Override: علامة تقول “أنا أعيد تعريف دالة موجودة في الأب”
  • is-a relationship: الطالب “هو” شخص، Student is a Person
  • جافا تدعم وراثة واحدة فقط: كلاس يرث من كلاس واحد بس (مو مثل C++)

تعدد الأشكال هو الموضوع اللي يفصل بين “أفهم OOP سطحيا” و”أفهم OOP فعلا”. لو حسيت إنه معقد، هذا طبيعي، ركّز على الأمثلة وجرّبها بنفسك.

4. تعدد الأشكال، Polymorphism

تعدد الأشكال يعني إن نفس العملية تتصرف بشكل مختلف حسب نوع الكائن. فيه نوعين:

Compile-time Polymorphism (Method Overloading)

نفس اسم الدالة بس بارامترات مختلفة. هذا تعلمته في CPCS 202:

public class Calculator {
    public int add(int a, int b) { return a + b; }
    public double add(double a, double b) { return a + b; }
    public int add(int a, int b, int c) { return a + b + c; }
}

Runtime Polymorphism (Method Overriding + Dynamic Binding)

هنا القوة الحقيقية، نفس الدالة تتصرف مختلف حسب نوع الكائن الفعلي:

// متغير نوعه الأب، لكن الكائن من الابن
Person p1 = new Student("أحمد", 20, 123);
Person p2 = new Employee("خالد", 35, "تقنية المعلومات");

p1.introduce(); // تستدعي نسخة Student
p2.introduce(); // تستدعي نسخة Employee

نقدر نحطهم في مصفوفة من نوع الأب ونتعامل معهم بشكل موحّد:

Person[] people = {p1, p2};
for (Person p : people) {
    p.introduce(); // كل كائن يستدعي نسخته
    System.out.println("---");
}

ℹ️ ليش تعدد الأشكال مهم؟

تخيّل عندك نظام فيه 20 نوع شكل هندسي (مربع، دائرة، مثلث…). بدل ما تكتب دالة لحساب المساحة لكل نوع، تكتب دالة واحدة calculateArea() في الكلاس الأب وكل شكل يعرّفها بطريقته. كود أقل، مرونة أكبر.

واجب Polymorphism محيّرك؟

كثير من طلاب CPCS 203 يواجهون صعوبة في تعدد الأشكال وتتبع الكود. أرسل لنا الواجب على واتساب ونساعدك تفهمه وتحله خطوة بخطوة.

أرسل واجبك على واتساب

5. التجريد والواجهات، Abstract Classes & Interfaces

Abstract Class

كلاس ما تقدر تنشئ منه كائن مباشرة. هو بس قالب للكلاسات اللي ترث منه:

public abstract class Shape {
    String color;

    public Shape(String color) { this.color = color; }

    public abstract double getArea(); // الأبناء يعرّفونها

    public void display() {
        System.out.println("اللون: " + color + " المساحة: " + getArea());
    }
}

لاحظ إن getArea() ما لها جسم، كل كلاس ابن لازم يكتب تعريفه الخاص. هذا هو التجريد: نحدد ماذا بدون كيف.

public class Circle extends Shape {
    double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    @Override
    public double getArea() { return Math.PI * radius * radius; }
}

نفس الفكرة مع المستطيل، يرث من Shape ويعرّف getArea() بطريقته:

public class Rectangle extends Shape {
    double width, height;

    public Rectangle(String color, double w, double h) {
        super(color);
        this.width = w;
        this.height = h;
    }

    @Override
    public double getArea() { return width * height; }
}

Interface

الواجهة (Interface) تحدد ماذا يجب أن يفعل الكلاس بدون أن تحدد كيف:

public interface Printable {
    void print(); // عقد بدون تعريف
}

public interface Saveable {
    void save(String filename);
}

الكلاس اللي ينفّذ الواجهة لازم يعرّف كل الدوال الموجودة فيها. ويقدر ينفّذ أكثر من واجهة:

public class Report implements Printable, Saveable {
    String content;

    public Report(String content) { this.content = content; }

    @Override
    public void print() { System.out.println("طباعة: " + content); }

    @Override
    public void save(String filename) { System.out.println("حفظ في: " + filename); }
}

💡 الفرق بين Abstract Class و Interface

  • Abstract Class: يقدر يحتوي دوال معرّفة + دوال مجرّدة + متغيرات. الكلاس يرث من abstract class واحد فقط.
  • Interface: بشكل عام دوال بدون تعريف فقط. الكلاس يقدر ينفّذ أكثر من interface.
  • القاعدة البسيطة: استخدم abstract class لما فيه كود مشترك، واستخدم interface لما تبي تحدد “عقد” فقط.

مشروعك يحتاج Abstract و Interface وما تدري تبدأ من وين؟

فريقنا ساعد عشرات الطلاب في تصميم مشاريع OOP. أرسل لنا متطلبات مشروعك واحصل على عرض سعر مجاني خلال ساعة.

أرسل متطلبات مشروعك

6. معالجة الاستثناءات، Exception Handling

البرنامج ممكن يواجه أخطاء وقت التشغيل (مثل: قسمة على صفر، ملف مو موجود، مدخل خاطئ). بدل ما البرنامج يتوقف، تتعامل مع الخطأ بشكل ذكي.

Scanner input = new Scanner(System.in);

try {
    System.out.print("أدخل البسط: ");
    int num = input.nextInt();
    System.out.print("أدخل المقام: ");
    int den = input.nextInt();
    System.out.println("الناتج: " + num / den);

} catch (ArithmeticException e) {
    System.out.println("خطأ: القسمة على صفر!");
} catch (InputMismatchException e) {
    System.out.println("خطأ: أدخل أرقام فقط!");
} finally {
    System.out.println("شكرا لاستخدام البرنامج");
    input.close();
}

أنواع الاستثناءات المهمة

الاستثناءالسبب
ArithmeticExceptionالقسمة على صفر
ArrayIndexOutOfBoundsExceptionفهرس خارج حدود المصفوفة
NullPointerExceptionمحاولة استخدام كائن قيمته null
InputMismatchExceptionمدخل بنوع خاطئ
FileNotFoundExceptionملف مو موجود

7. التعامل مع الملفات، File I/O

تبي برنامجك يقرأ بيانات من ملف أو يحفظ نتائج في ملف؟ هذا الموضوع يعلمك كيف.

الكتابة في ملف

try {
    PrintWriter writer = new PrintWriter("students.txt");
    writer.println("أحمد,1234,4.5");
    writer.println("سارة,5678,3.8");
    writer.println("خالد,9012,4.2");
    writer.close(); // مهم! بدون close ما تتحفظ
    System.out.println("تم الحفظ بنجاح");
} catch (FileNotFoundException e) {
    System.out.println("خطأ في إنشاء الملف");
}

القراءة من ملف

try {
    Scanner reader = new Scanner(new File("students.txt"));

    while (reader.hasNextLine()) {
        String[] parts = reader.nextLine().split(","); // تقسيم بالفاصلة
        String name = parts[0];
        double gpa = Double.parseDouble(parts[2]);
        System.out.println(name + " - معدل: " + gpa);
    }
    reader.close();

} catch (FileNotFoundException e) {
    System.out.println("الملف غير موجود!");
}

⚠️ لا تنسى close()!

لما تفتح ملف للكتابة، لازم تسوي close() عشان البيانات تتحفظ فعلا. نسيان close() من أكثر الأخطاء اللي تخسّر درجات في اللاب والاختبار.

8. مصفوفات الكائنات، Arrays of Objects

في الحياة الحقيقية، عادة عندك مجموعة كائنات (قائمة طلاب، قائمة منتجات). هنا تتعلم كيف تتعامل معها:

Student[] students = new Student[3];
students[0] = new Student("أحمد", 101, 4.5);
students[1] = new Student("سارة", 102, 3.8);
students[2] = new Student("خالد", 103, 4.2);

مثال عملي: إيجاد الطالب صاحب أعلى معدل بالمرور على المصفوفة:

Student top = students[0];
for (int i = 1; i < students.length; i++) {
    if (students[i].getGpa() > top.getGpa())
        top = students[i];
}
System.out.println("أعلى معدل: " + top.getName());

أنواع أسئلة الاختبارات في CPCS 203

أنواع الأسئلة المتوقعة

  1. تتبع الكود (Trace): يعطيك كود فيه وراثة أو polymorphism ويسألك عن المخرجات. هذا النوع ياخذ نص الاختبار تقريبا، تدرّب عليه كثير
  2. اكتب كلاس: يعطيك وصف ويطلب منك تكتب كلاس كامل مع constructors, getters/setters, ودوال
  3. أكمل الكود: يعطيك كود ناقص وتكمّله
  4. اشرح المفهوم: “ما الفرق بين overloading و overriding؟” أو “اشرح التغليف مع مثال”
  5. اكتشاف الأخطاء: كود فيه أخطاء في OOP وتصلحها
  6. UML: أحيانا يطلبون ترسم أو تقرأ class diagram بسيط

نصائح للواجبات واختبار اللاب النهائي

الواجبان في CPCS 203 برمجة عملية بالكامل — ما فيه أسئلة نظرية. كل واجب يطلب منك تكتب كلاسات وتطبّق مفهوم معين. واختبار اللاب النهائي نفس الفكرة، تحل برنامج كامل في وقت محدد داخل اللاب.

كيف تحضّر للواجبات واختبار اللاب

  1. افهم المطلوب أولا: اقرأ الواجب كامل قبل ما تفتح الـ IDE، وحدد الكلاسات المطلوبة
  2. ارسم العلاقات على ورقة: قبل الكود، ارسم أي كلاس يرث من أي، وأي خصائص لكل كلاس
  3. ابدأ بالهيكل: اكتب الكلاسات الفارغة مع constructors وgetters/setters أولا
  4. اختبر كل جزء لحاله: لا تنتظر تخلص كل شيء عشان تجرب
  5. تدرّب على الوقت: في اختبار اللاب وقتك محدود - تدرّب تكتب كلاسات بسرعة

💡 للاختبار العملي النهائي

راجع الواجبين اللي سلّمتهم خلال الفصل - اختبار اللاب عادة في نفس مستواهم. تدرّب تكتب كلاس كامل بـ constructor وgetters/setters وmethod في أقل من 10 دقائق.

واجب CPCS 203 صعب عليك؟

فريقنا متخصص في واجبات OOP بجافا. أرسل لنا الواجب على واتساب ونرد عليك بعرض سعر خلال ساعة.

أرسل واجبك على واتساب

ربط المادة بمسارك الأكاديمي

بعد CPCS 203، المادة التالية في مسار البرمجة هي CPCS 204، هياكل البيانات 1. في CPCS 204 راح تستخدم كل مفاهيم OOP اللي تعلمتها هنا لبناء هياكل بيانات مثل القوائم المتصلة والأشجار والمكدسات.

لو تبي شرح أعمق لأساسيات جافا، اقرأ دليلنا الشامل لتعلم جافا. ولو تبي تقرأ عن المادة اللي بعدها، اقرأ شرح مادة CPCS 204 هياكل البيانات 1.

خلاصة

مادة CPCS 203 مو بس مادة تجيب فيها درجة. هي الفارق بين طالب يكتب كود “يشتغل” وطالب يصمم نظام ينبني عليه. كل مشروع ستسويه من بعدها — في هياكل البيانات، هندسة البرمجيات، أو حتى لو طوّرت تطبيق بمفردك — راح تلاقي نفسك ترجع لهذه المفاهيم من غير ما تحس.

نصيحة أخيرة: لو في موضوع واحد تبي تتقنه قبل الاختبار النهائي، خلّه Polymorphism وتتبع الكود. هذا النوع من الأسئلة ياخذ نص درجات الاختبار تقريبا، وما يمشي بالحفظ — لازم تفهمه. افتح IDE وجرّب كل مثال في هذا المقال، وبعدين عدّله وشوف وش يصير.

واجبات، مشاريع، أو تحضير اختبار CPCS 203؟

فريق زدني متخصص في مواد كلية الحاسبات بجامعة الملك عبدالعزيز. أرسل لنا تفاصيل اللي تحتاجه وراح نرد عليك خلال ساعة.

تواصل معنا عبر واتساب
هل تحتاج خصوصي؟