Static func vs class func في Swift: دليل شامل للمطورين
\n\nكل من يكتب بلغة Swift، عاجلاً أم آجلاً، يواجه معضلة: static func أم class func؟ للوهلة الأولى، تعمل كلتا الكلمتين المفتاحيتين على إنشاء دوال على مستوى النوع. لكن الفرق بينهما ليس مجرد نزوة نحوية، بل هو اختلاف جوهري يتعلق بالوراثة وتعدد الأشكال. في هذه المقالة، سنوضح مرة واحدة وإلى الأبد الفرق بين static func و class func في Swift، ومتى نستخدم كل منهما، وكيف ستساعدك هذه المعرفة في كتابة كود أكثر نظافة ومرونة.
\n\nما هي دوال النوع في Swift؟
\n\nقبل الغوص في الاختلافات، دعنا نتذكر الأساسيات. في Swift، تنقسم الدوال إلى نوعين:
\n\n- \n
- دوال الكائن (instance methods) — يتم استدعاؤها على كائن معين من الفئة أو الهيكل أو التعداد. \n
- دوال النوع (type methods) — يتم استدعاؤها على النوع نفسه، وليس على كائنه. للإعلان عنها، تُستخدم الكلمات المفتاحية
staticأوclass. \n
دوال النوع مثالية لدوال المصنع، والمفردات (singletons)، والدوال المساعدة، والإعدادات غير المرتبطة بحالة كائن معين.
\n\nStatic func: الحارس الرئيسي للثبات
\n\nstatic func هي دالة لا يمكن إعادة تعريفها (override) في الفئة الفرعية. إنها تنتمي حصريًا إلى النوع الذي تم تعريفها فيه. تعمل الكلمة المفتاحية static بنفس الطريقة مع الفئات والهياكل والتعدادات.
مثال: static func في فئة
\n\nclass Animal {\n static func describe() {\n print("أنا حيوان. لا يمكن تغيير جوهرتي.")\n }\n \n func speak() {\n print("أصدر صوتًا")\n }\n}\n\nclass Dog: Animal {\n // خطأ! لا يمكن إعادة تعريف دالة static\n // override static func describe() { }\n \n override func speak() {\n print("هاو هاو!")\n }\n}\n\n// الاستخدام\nAnimal.describe() // "أنا حيوان. لا يمكن تغيير جوهرتي."\nDog.describe() // أيضًا "أنا حيوان. لا يمكن تغيير جوهرتي."\n\n\nلاحظ: Dog.describe() يستدعي دالة الفئة الأم. على الرغم من أن الفئة الفرعية ترث الدالة الثابتة تقنيًا، إلا أنه لا يمكن إعادة تعريفها. هذا السلوك يشبه final class func.
Static func في الهياكل
\n\nالهياكل (أنواع القيم) تدعم أيضًا الدوال الثابتة:
\n\nstruct MathHelper {\n static func square(_ number: Int) -> Int {\n return number * number\n }\n}\n\nlet result = MathHelper.square(5) // 25\n\n\nنظرًا لأن الهياكل لا تدعم الوراثة، فإن static هنا هي الطريقة الوحيدة الممكنة للإعلان عن دالة من نوع.
Class func: مرونة الوراثة
\n\nclass func هي دالة من نوع يمكن إعادة تعريفها في الفئة الفرعية. وهي متاحة للفئات فقط (أنواع المرجع). لا يمكن للهياكل والتعدادات استخدام class.
مثال: class func وإعادة تعريفها
\n\nclass Vehicle {\n class func makeNoise() {\n print("المركبة تصدر ضوضاء")\n }\n \n class final func isMotorized() -> Bool {\n return true\n }\n}\n\nclass Car: Vehicle {\n override class func makeNoise() {\n print("السيارة تزمجر: برررر!")\n }\n \n // خطأ! لا يمكن إعادة تعريف final class func\n // override class func isMotorized() -> Bool { return false }\n}\n\n// الاستخدام\nVehicle.makeNoise() // "المركبة تصدر ضوضاء"\nCar.makeNoise() // "السيارة تزمجر: برررر!"\n\n\nكما ترى، تتصرف class func مثل دالة افتراضية عادية، ولكن يتم استدعاؤها على مستوى النوع. هذا يفتح إمكانيات لتعدد الأشكال على مستوى الفئات.