الفئة الأساسية '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().
التحدي
سهللنقم ببناء نظام مقارنة كتب يوضح كيف أن تجاوز (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}"
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injection