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

الفئة الأساسية 'object'

جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 23 من 70.

في لغة C#، كل فئة تقوم بإنشائها ترث تلقائياً من فئة خاصة تسمى object. حتى عندما لا تحدد فئة أساسية بشكل صريح، تظل فئتك تمتلك object كأصل نهائي لها. هذا يعني أن كل نوع في C# يشترك في مجموعة مشتركة من الأساليب.

توفر فئة object عدة دوال افتراضية يمكنك تجاوزها في فئاتك الخاصة:

public class Person
{
    public string Name { get; set; }
    
    // تجاوز من الكائن
    public override string ToString()
    {
        return $"Person: {Name}";
    }
    
    public override bool Equals(object obj)
    {
        if (obj is Person other)
            return Name == other.Name;
        return false;
    }
    
    public override int GetHashCode()
    {
        return Name?.GetHashCode() ?? 0;
    }
}

الطرق الثلاث الأكثر شيوعاً التي يتم تجاوزها هي ToString() لتمثيل السلسلة النصية، و Equals() لمقارنة الكائنات، و GetHashCode() للمجموعات القائمة على التجزئة. بشكل افتراضي، تعيد ToString() اسم النوع، وتتحقق Equals() من تساوي المراجع.

بما أن كل شيء يرث من object، يمكنك تخزين أي نوع في متغير object:

object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";

Console.WriteLine(item1.ToString());  // Person: Alice

هذه الفئة الأساسية العامة (universal base class) هي ما يجعل ميزات مثل المجموعات (collections) التي تحتوي على أنواع مختلطة ممكنة، وهذا هو السبب في أن كل كائن (object) في لغة C# لديه وصول إلى دوال (methods) مثل ToString() و GetType().

challenge icon

التحدي

سهل

لنقم ببناء نظام مقارنة كتب يوضح كيف أن تجاوز (overriding) الأساليب من الفئة الأساسية object يمنح أنواعك المخصصة سلوكاً ذا معنى لتمثيل السلسلة النصية والتحقق من التساوي.

ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:

  • Book.cs: قم بتعريف فئة Book داخل مساحة الأسماء Library. يجب أن يحتوي الكتاب على خصائص Title (سلسلة نصية) و Author (سلسلة نصية)، بالإضافة إلى منشئ (constructor) يضبط كلتا القيمتين. قم بتجاوز الأساليب الثلاثة الرئيسية الموروثة من object:
    • يجب أن يعيد ToString() القيمة "{Title} by {Author}"
    • يجب أن يعيد Equals(object obj) القيمة true إذا كان الكائن الآخر هو Book وله نفس Title و Author
    • يجب أن يجمع GetHashCode() بين رموز التجزئة (hash codes) لكلتا الخاصيتين
  • Program.cs: في ملفك الرئيسي، قم بإنشاء كتابين باستخدام قيم الإدخال. اعرض كل كتاب باستخدام ToString()، ثم تحقق مما إذا كانا متساويين واطبع النتيجة. أخيراً، وضح أنه يمكنك تخزين Book في متغير من نوع object ولا تزال تحصل على مخرجات ذات معنى عند استدعاء ToString().

ستتلقى أربعة مدخلات:

  • عنوان الكتاب الأول
  • مؤلف الكتاب الأول
  • عنوان الكتاب الثاني
  • مؤلف الكتاب الثاني

اطبع المخرجات بهذا التنسيق:

Book 1: {ToString result}
Book 2: {ToString result}
Are they equal? {True/False}
Stored as object: {ToString result of first book stored in object variable}

على سبيل المثال، إذا كانت المدخلات هي 1984، و George Orwell، و 1984، و George Orwell، فيجب أن تكون المخرجات:

Book 1: 1984 by George Orwell
Book 2: 1984 by George Orwell
Are they equal? True
Stored as object: 1984 by George Orwell

إذا كانت المدخلات هي 1984، و George Orwell، و Brave New World، و Aldous Huxley، فيجب أن تكون المخرجات:

Book 1: 1984 by George Orwell
Book 2: Brave New World by Aldous Huxley
Are they equal? False
Stored as object: 1984 by George Orwell

لاحظ كيف تمنح الأساليب التي تم تجاوزها كائنات Book سلوكاً ذا معنى - فهي تظهر بشكل جيد كسلاسل نصية ويمكن مقارنتها بمحتواها بدلاً من مجرد مراجع الذاكرة الخاصة بها!

ورقة مرجعية

في لغة #C، ترث كل فئة تلقائيًا من فئة object، والتي توفر العديد من الأساليب الافتراضية (virtual methods) التي يمكن تجاوزها (overridden):

أساليب الكائن الشائعة التي يمكن تجاوزها

  • ToString() - يعيد تمثيلاً نصياً للكائن (الافتراضي يعيد اسم النوع)
  • Equals(object obj) - يقارن الكائنات من حيث التساوي (الافتراضي يتحقق من تساوي المراجع)
  • GetHashCode() - يعيد رمز التجزئة (hash code) لاستخدامه في المجموعات القائمة على التجزئة

تجاوز أساليب الكائن

public class Person
{
    public string Name { get; set; }
    
    // تجاوز ToString للحصول على تمثيل نصي مخصص
    public override string ToString()
    {
        return $"Person: {Name}";
    }
    
    // تجاوز Equals للمقارنة بناءً على المحتوى
    public override bool Equals(object obj)
    {
        if (obj is Person other)
            return Name == other.Name;
        return false;
    }
    
    // تجاوز GetHashCode للمجموعات القائمة على التجزئة
    public override int GetHashCode()
    {
        return Name?.GetHashCode() ?? 0;
    }
}

الفئة الأساسية العامة

يمكن تخزين أي نوع في متغير من نوع object:

object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";

Console.WriteLine(item1.ToString());  // Person: Alice

يتيح هذا الميراث العام إنشاء مجموعات تحتوي على أنواع مختلطة ويضمن وصول كل كائن إلى أساليب مثل ToString() و GetType().

جرّب بنفسك

using System;
using Library;

class Program
{
    public static void Main(string[] args)
    {
        // قراءة المدخلات لكتابين
        string title1 = Console.ReadLine();
        string author1 = Console.ReadLine();
        string title2 = Console.ReadLine();
        string author2 = Console.ReadLine();

        // TODO: إنشاء كائنين من النوع Book باستخدام قيم المدخلات

        // TODO: طباعة Book 1 باستخدام ToString()
        // التنسيق: "Book 1: {ToString result}"

        // TODO: طباعة Book 2 باستخدام ToString()
        // التنسيق: "Book 2: {ToString result}"

        // TODO: التحقق مما إذا كان الكتابان متساويين وطباعة النتيجة
        // التنسيق: "Are they equal? {True/False}"

        // TODO: تخزين الكتاب الأول في متغير من نوع object وطباعته
        // التنسيق: "Stored as object: {ToString result}"
    }
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming