المُنشئ (البرمجة الكائنية التوجه)

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

يشبه المُنشئ طريقة الكائن ، لكنه يختلف عنها في أنه لا يُرجع قيمةً صريحة ، ولا يُورَث ضمنيًا ، وعادةً ما تكون له قواعد مختلفة لمُعدِّلات النطاق. غالبًا ما يحمل المُنشئ نفس اسم الفئة المُعلنة . وتتمثل مهمته في تهيئة أعضاء بيانات الكائن وتحديد ثوابت الفئة ، ويفشل إذا كانت هذه الثوابت غير صالحة. يُبقي المُنشئ المكتوب بشكل صحيح الكائن الناتج في حالة صالحة . يجب تهيئة الكائنات غير القابلة للتغيير في مُنشئ.

تسمح معظم لغات البرمجة بتحميل المُنشئات بشكل زائد ، حيث يمكن أن يكون هناك أكثر من مُنشئ واحد لنفس الصنف، بمعاملات مختلفة. وتأخذ بعض اللغات في الاعتبار أنواعًا خاصة من المُنشئات. تُجرّد المصانع المُنشئات، التي تستخدم صنفًا واحدًا لإنشاء كائنات وإرجاع نسخة جديدة من ذلك الصنف، حيث تقوم المصانع أيضًا بإنشاء كائنات ولكن بطرق متنوعة، باستخدام أصناف متعددة أو أنظمة تخصيص مختلفة مثل مجمع الكائنات .

الأنواع

المُنشئات المُعَلمة

تُسمى الدوال البانية التي تقبل وسيطًا واحدًا على الأقل بالدوال البانية المُعاملة. عند تعريف كائن في دالة بانية مُعاملة، يجب تمرير القيم الأولية كوسائط إلى الدالة البانية. قد لا تنجح الطريقة العادية لتعريف الكائن. يمكن استدعاء الدوال البانية صراحةً أو ضمنيًا. تُسمى طريقة الاستدعاء الضمني للدالة البانية أيضًا بالطريقة المختصرة.

class Point { private : int x ; int y ; public : Point () = default ; Point ( int x , int y ) : x { x }, y { y } {} // مُنشئ مُعامل };
Point p = Point ( 0 , 50 ); // استدعاء صريح. Point p2 ( 0 , 50 ); // استدعاء ضمني.

المُنشئات الافتراضية

إذا لم يُحدد المبرمج مُنشئًا لفئة قابلة للإنشاء، يُدرج مُترجم جافا مُنشئًا افتراضيًا في الكود. يُعرف هذا المُنشئ بالمُنشئ الافتراضي. لا يوجد هذا المُنشئ في الكود المصدري ( ملف .java ) لأنه يُدرج أثناء الترجمة ويوجد في ملف .class . يختلف سلوك المُنشئ الافتراضي باختلاف لغة البرمجة. فقد يُهيئ أعضاء البيانات إلى الصفر أو قيم مُماثلة، أو قد لا يفعل شيئًا على الإطلاق. في جافا، يُشير مصطلح "المُنشئ الافتراضي" إلى مُنشئ فارغ يُنشئه المُترجم تلقائيًا إذا لم يتم تعريف أي مُنشئات للفئة أو في حال عدم وجود أي مُنشئات مُعرّفة من قِبل المبرمج (على سبيل المثال، في جافا، يستدعي المُنشئ الافتراضي ضمنيًا المُنشئ الفارغ للفئة الأصلية ، ثم يُنفذ جسمًا فارغًا). تبقى جميع الحقول على قيمتها الأولية (للأنواع الصحيحة)، أو (للأنواع العشرية)، أو (للأنواع المنطقية)، أو (للأنواع المرجعية)، إلخ.00.0falsenull

class Point { private : int x ; int y ; public : Point ( int x = 0 , int y = 0 ); // المُنشئ الافتراضي. };

منشئات النسخ

تدعم لغة جافا، مثل لغة C++، "المنشئات النسخية". ولكن، على عكس C++، لا تُنشئ جافا منشئ نسخ افتراضيًا حتى في حال عدم تحديده. تُحدد المنشئات النسخية الإجراءات التي يُنفذها المُصرّف عند نسخ كائنات الفئة. يحتوي منشئ النسخ على مُعامل رسمي واحد يُمثل نوع الفئة (قد يكون المُعامل مرجعًا لكائن). يُستخدم لإنشاء نسخة من كائن موجود من نفس الفئة. على الرغم من أن الفئتين متطابقتان، إلا أنه يُعتبر منشئ تحويل. بينما يُختصر مصطلح المنشئات النسخية عادةً إلى "copy ctor" أو "cctor"، إلا أنه لا علاقة له بمنشئات الفئات المُستخدمة في .NET والتي تستخدم نفس الاختصار.

مُنشئات التحويل

تُتيح دوال التحويل للمُصرّف إنشاء كائن ضمنيًا ينتمي إلى فئة معينة بناءً على كائن من نوع مختلف. عادةً ما تُستدعى هذه الدوال ضمنيًا لتحويل الوسائط أو المعاملات إلى النوع المناسب، ولكن يمكن أيضًا استدعاؤها صراحةً.

نقل المُنشئات

في لغة C++، تأخذ دوال البناء النقلية مرجع قيمة يمين إلى كائن من الفئة، وتستخدم لتنفيذ نقل ملكية موارد كائن المعلمة.

بناء الجملة

  • تعتمد لغات البرمجة Java و C++ و C# و ActionScript و PHP 4 و MATLAB على اصطلاح تسمية حيث يكون للمنشئات نفس اسم الفئة التي ترتبط بها.
  • في لغتي البرمجة C و Rust ، لا توجد دوال إنشاء على مستوى اللغة. في C، تُنشأ الكائنات بواسطة مُهيئ البنية، أو دالة تُنشئ نسخة من هذا الكائن. وبالمثل في Rust، تُنشأ الكائنات كقيم حرفية للبنية، ولكن قد تتضمن أيضًا دالة مُرتبطة تُشبه دالة الإنشاء (عادةً ما تُسمى بـ ، إلخ).newfrom
  • في لغة Crystal ، كما هو الحال في لغة Python، ينقسم المُنشئ إلى طريقتين: `constructor` newو` constructor` initialize. يُعرّف المُصرّف newالطريقة `constructor`، ولا يتطلب من المستخدم سوى تعريف الطريقة `constructor` initialize. [ 1 ] على الرغم من أن مُصرّف Crystal يُعرّفها تلقائيًا، إلا أنه يُمكن للمستخدم تعريف الطريقة `constructor` يدويًا new، بل وحتى الاستغناء عن استخدام الطريقة الافتراضية newوتعريف مُنشئاته الخاصة.
  • في PHP 5، يُوصى باستخدام اسم `constructor` للدالة __constructالبانية. ولضمان التوافق مع الإصدارات السابقة، سيتم استدعاء دالة تحمل نفس اسم الفئة إذا __constructلم يتم العثور على الدالة `constructor`. منذ PHP 5.3.3، يعمل هذا فقط مع الفئات غير المُعرّفة بمساحات أسماء. [ 2 ]
  • في PHP 7، يجب عليك دائمًا تسمية الدالة البانية باسم __construct. ستؤدي الدوال التي تحمل نفس اسم الفئة إلى ظهور خطأ من المستوى E_DEPRECATED. [ 2 ]
  • في لغة بيرل ، يتم تسمية الدوال البانية، وفقًا للاتفاقية، بـ "new" ويتعين عليها القيام بقدر كبير من إنشاء الكائنات.
  • في نظام كائنات Moose للغة Perl، newيتم إنشاء المنشئات (المسماة) تلقائيًا ويتم توسيعها عن طريق تحديد BUILDطريقة.
  • في Visual Basic .NET ، يتم استدعاء الدالة البانية " New".
  • في لغة بايثون ، يُقسّم المُنشئ إلى دالتين، هما " __new__" و " __init__". __new__الدالة الأولى مسؤولة عن تخصيص الذاكرة للكائن، وتستقبل الكائن كوسيط (وتُسمى عادةً " cls"). أما __init__الدالة الثانية (التي تُسمى غالبًا "المُهيئ") فتستقبل الكائن المُنشأ حديثًا كوسيط (وتُسمى عادةً " self"). [ 3 ]
  • يتم الإشارة إلى مُنشئات Object Pascal بالكلمة المفتاحية " constructor" ويمكن أن يكون لها أسماء محددة من قبل المستخدم (ولكن يتم تسميتها في الغالب " Create").
  • في لغة Objective-C ، تُقسّم دالة البناء إلى دالتين، الأولى تُخصّص الذاكرة لنسخة من الصنف، allocوالثانية تتولى الجزء الأكبر من تهيئة هذه النسخة. يؤدي استدعاء الدالة الأولى إلى استدعاء كلتا الدالتين، الأولى والثانية ، لنسخة الصنف.initallocinitnewallocinit

تنظيم الذاكرة

في لغات Java وC# وVB .NET، يُنشئ المُنشئ كائنات من نوع مرجعي في الذاكرة الديناميكية (heap)، بينما تُخزَّن الأنواع الأولية (مثل int`int` و`int` و`int` وما إلى ذلك) في مكدس الذاكرة ( stack ) (مع أن بعض اللغات تسمح بتخصيص الكائنات يدويًا في مكدس الذاكرة باستخدام مُعدِّل). كما تسمح لغتا VB .NET وC# باستخدام عامل التشغيل `require` لإنشاء كائنات من نوع قيمة، ولكن تُنشأ هذه الكائنات في مكدس الذاكرة بغض النظر عن استخدام عامل التشغيل `require` أم لا. في هذه اللغات، يحدث تدمير الكائن عندما لا يكون له أي مراجع، ثم يقوم جامع البيانات المهملة بتدميره.doublestackallocnew

في لغة C++، تُنشأ الكائنات على المكدس عند استدعاء الدالة البانية بدون newعامل التشغيل، وتُنشأ على الكومة عند استدعاء الدالة البانية مع newعامل التشغيل (الذي يُعيد مؤشرًا إلى الكائن). تُحذف كائنات المكدس ضمنيًا عند خروجها من نطاق التعريف، بينما يجب حذف كائنات الكومة ضمنيًا بواسطة الدالة الهدامة أو صراحةً باستخدام deleteعامل التشغيل. باستخدام أسلوب " اكتساب الموارد هو التهيئة " (RAII)، يُمكن تبسيط إدارة الموارد بشكل كبير.

تفاصيل اللغة

يتم تنفيذ الدوال البانية في لغات البرمجة المختلفة بطرق متنوعة، بما في ذلك:

ج

في لغة C ، لا توجد دوال إنشاء. ومع ذلك، يمكن تعريف الدوال لإنشاء كائن، على غرار دالة الإنشاء.

#include <stdlib.h>typedef struct { char * name ; int age ; } Person ;// تُنشئ هذه الطريقة نسخة من الكائن Person * createPerson ( const char name [ ], int age ) { Person * p = ( Person * ) malloc ( sizeof ( Person )); if ( ! p ) { return NULL ; } strcpy ( p -> name , name ); p -> age = age ; return p ; }// هذه الطريقة تُدمر نسخة من الكائن Person void destroyPerson ( Person * p ) { if ( p ) { free ( p -> name ); free ( p ); } }

لغة سي++

في لغة C++ ، اسم الدالة البانية هو اسم الصنف. وهي لا تُرجع أي قيمة. ويمكن أن تحتوي على معاملات مثل أي دالة عضوية . عادةً ما تُعلن الدوال البانية في القسم العام، ولكن يمكن أيضًا إعلانها في القسمين المحمي والخاص، إذا رغب المستخدم في تقييد الوصول إليها.

يتكون المُنشئ من جزأين. الأول هو قائمة التهيئة التي تلي قائمة المعاملات وتسبق جسم الدالة. تبدأ هذه القائمة بنقطتين رأسيتين، وتُفصل عناصرها بفواصل. قائمة التهيئة اختيارية، ولكنها تُتيح إمكانية تحديد قيم لأعضاء البيانات وتجنب استخدام عبارات إسناد منفصلة. تُصبح قائمة التهيئة إلزامية في حال وجود constأعضاء بيانات من نوع مرجعي، أو أعضاء لا تحتوي على منطق مُنشئ بدون معاملات. تتم عمليات الإسناد وفقًا لترتيب تعريف أعضاء البيانات (حتى لو كان ترتيبها في قائمة التهيئة مختلفًا). [ 4 ] أما الجزء الثاني فهو جسم الدالة، وهو جسم دالة عادي مُحاط بأقواس معقوفة. من الأفضل عمومًا استخدام قائمة التهيئة قدر الإمكان، واستخدام جسم المُنشئ فقط للعمليات التي لا تتطلب إسناد قيم، أو في حالات الإسناد التي لا يُمكن فيها استخدام قائمة التهيئة أو تكون غير كافية.

تسمح لغة C++ بأكثر من مُنشئ واحد. يجب أن تحتوي المُنشئات الأخرى على مُعاملات مختلفة. بالإضافة إلى ذلك، يجب أن تلتزم المُنشئات التي تحتوي على مُعاملات ذات قيم افتراضية بشرط عدم إعطاء جميع المُعاملات قيمة افتراضية. هذا الشرط مهم فقط في حالة وجود مُنشئ افتراضي. يمكن أيضًا استدعاء مُنشئ الفئة الأساسية (أو الفئات الأساسية) من قِبل فئة مشتقة. لا تُورَث دوال المُنشئ، ولا يمكن الإشارة إلى عناوينها. عند الحاجة إلى تخصيص الذاكرة، يتم استدعاء المعاملين ` newand` ضمنيًا.delete

يحتوي المُنشئ النسخي على مُعامل من نفس النوع مُمرر constكمرجع، على سبيل المثال . إذا لم يتم توفيره صراحةً، يستخدم المُصرّف المُنشئ النسخي لكل مُتغير عضو، أو ببساطة ينسخ القيم في حالة الأنواع الأولية. لا يكون التنفيذ الافتراضي فعالاً إذا كانت الفئة تحتوي على أعضاء مُخصصة ديناميكيًا (أو مؤشرات لموارد أخرى)، لأنه قد يؤدي إلى استدعاءات مُزدوجة (أو تحرير مُزدوج للموارد) عند التدمير.X(constX&rhs)delete

استيراد std ؛class PolarPoint { private : double x ; double y ; public : explicit PolarPoint ( double r = 1.0 , double theta = 0.0 ) : // المُنشئ، المعاملات بقيم افتراضية. x { r * std::cos ( theta ) }, y { r * std :: sin ( theta ) } /* <- قائمة التهيئة */ { std :: println ( "النقطة: x = {}, y = {}" , x , y ); // جسم المُنشئ } };

أمثلة على الاستدعاءات:

بولار بوينت أ ; بولار بوينت ب ( 3 ) ؛ PolarPoint ج ( 5 , ستد :: أرقام :: بي / 4 );

عند إرجاع الكائنات من الدوال أو تمرير الكائنات بالقيمة، سيتم استدعاء منشئ النسخ للكائنات ضمنيًا، ما لم يتم تطبيق تحسين قيمة الإرجاع .

تُنشئ لغة C++ ضمنيًا مُنشئ نسخ افتراضيًا يستدعي مُنشئات النسخ لجميع الفئات الأساسية وجميع متغيرات الأعضاء، ما لم يُوفر المبرمج مُنشئ نسخ، أو يحذف مُنشئ النسخ صراحةً (لمنع الاستنساخ)، أو يُحذف مُنشئ النسخ لأحد الفئات الأساسية أو متغيرات الأعضاء، أو يكون غير قابل للوصول إليه (خاص). في معظم الحالات التي تتطلب مُنشئ نسخ مُخصص (مثل عد المراجع ، والنسخ العميق للمؤشرات)، يلزم أيضًا تخصيص مُدمر النسخ وعامل إسناد النسخ . يُشار إلى هذا عادةً باسم قاعدة الثلاثة .

سي شارب

مثال على دالة البناء في لغة C# :

public class MyClass { private int a ; private string b ;// الدالة البانية العامة MyClass () : this ( 42 , "string" ) { }// تحميل زائد للدالة البانية public MyClass ( int a , string b ) { this . a = a ; this . b = b ; } }
// الكود موجود في مكان ما // إنشاء كائن باستخدام المُنشئ أعلاه MyClass c = new MyClass ( 42 , "string" );

منذ إصدار C# 9.0، أصبح بالإمكان تبسيط استدعاءات المُنشئ باستخدام تعابير مُحددة النوع new، والتي لا تتطلب تسمية المُنشئ عندما يكون النوع مُحددًا مُسبقًا. سيتم استدعاء مُنشئ النوع المُسمى تلقائيًا قبل المتغير، ولكن من الواضح أنه لن يتم حله إذا تم استخدام استنتاج النوع var. [ 5 ]

// المثال أعلاه مع تعبيرات جديدة من نوع الهدف MyClass c = new ( 42 , "string" );

مُنشئ ثابت في لغة C#

في لغة C# ، يُعد المُنشئ الثابت مُهيئًا ثابتًا للبيانات. [ 6 ] : 111-112. تُسمى المُنشئات الثابتة أيضًا مُنشئات الأصناف . ولأن اسم الدالة المُولّدة هو .cctor، فإنها تُسمى غالبًا "cctors". [ 7 ] [ 8 ]

تسمح المُنشئات الثابتة بتهيئة المتغيرات الثابتة المعقدة . [ 9 ] تُستدعى المُنشئات الثابتة ضمنيًا عند الوصول إلى الصنف لأول مرة. أي استدعاء للصنف (ثابت أو استدعاء مُنشئ) يُفعّل تنفيذ المُنشئ الثابت. المُنشئات الثابتة آمنة للاستخدام في بيئات متعددة الخيوط وتُطبّق نمط التصميم Singleton . عند استخدامها في صنف برمجة عام ، تُستدعى المُنشئات الثابتة عند كل إنشاء جديد للصنف العام، مُنشئ واحد لكل نوع. [ 10 ] : 38 [ 6 ] : 111 كما تُنشأ المتغيرات الثابتة أيضًا.

public class MyClass { private static int _A ;// دالة البناء العادية الثابتة MyClass () { _A = 32 ; }// المُنشئ الافتراضي القياسي public MyClass () {} }
// الكود موجود في مكان ما // إنشاء كائن باستخدام المُنشئ أعلاه // قبل الإنشاء مباشرةً // يتم تنفيذ المُنشئ الثابت للمتغير و _A = 32 MyClass c = new MyClass ();

لغة ترميز ColdFusion (CFML)

تستخدم لغة ترميز ColdFusion (CFML) طريقة تسمى ' init' كطريقة بناء.

جبن.cfc

component { // خصائص اسم الخاصية = "cheeseName" ;// دالة البناء Cheese init ( required string cheeseName ) { variables . cheeseName = arguments . cheeseName ; return this ; } }

أنشئ نسخة من الجبن.

myCheese = new Cheese ( 'Cheddar' );

منذ الإصدار 10 من ColdFusion، [ 11 ] يدعم CFML أيضًا تحديد اسم طريقة البناء:

component initmethod = "Cheese" { // خصائص property name = "cheeseName" ;// دالة البناء Cheese Cheese ( مطلوب سلسلة cheeseName ) { variables.cheeseName = arguments.cheeseName ; return this ; } }

كريستال

في لغة Crystal، يُعرّف المستخدم initializeدالةً، يستخدمها المُصرّف لتعريف newدالةٍ لتخصيص الذاكرة للكائن واستدعاء الدالة المُعرّفة من قِبل المستخدم. كما يُمكن للمستخدم تعريف دالةٍ يدويًا newأو تعريف دالةٍ مُكافئة باسمٍ مُختلف، إذا رغب في ذلك ( يُعرض هنا رمز كلتا الدالتين). على الرغم من أن هذا المقتطف يُعرّف دالة initialize، إلا أن الإجراء مُطابقٌ في لغة Crystal.newclassstruct

class Car # الدالة المُهيئة، وهي دالة خاصة بالمثيل. def initialize ( make : String , year : Int ) @make = make @year = year end # الدالة المُخصصة للذاكرة، وهي دالة خاصة بالفئة، ويُشار إليها بالبادئة "self". # لاحظ أن `new` تأخذ نفس وسائط `initialize` . def self.new ( make : String , year : Int ) # تخصيص الذاكرة للمثيل instance = Car.allocate # استدعاء دالة initialize الخاصة بالمثيل باستخدام المعاملات المُقدمة instance.initialize make , year # إرجاع المثيل instance end end# إنشاء نسخة جديدة من `Car` على النحو التالي: old_car = Car.new ( " Chevrolet " , 1947 )

إيفل

في لغة إيفل ، تُسمى الإجراءات التي تُهيئ الكائنات الجديدة بإجراءات الإنشاء . وتتميز إجراءات الإنشاء بالخصائص التالية:

  • لا تحتوي إجراءات الإنشاء على نوع إرجاع صريح (بحسب تعريف الإجراء ). [ أ ]
  • يتم تسمية إجراءات الإنشاء.
  • تُسمى إجراءات الإنشاء في نص الفئة.
  • يمكن استدعاء إجراءات الإنشاء بشكل صريح لإعادة تهيئة الكائنات الموجودة.
  • يجب أن تحدد كل فئة فعالة (أي ملموسة أو غير مجردة) إجراء إنشاء واحد على الأقل.
  • يجب أن تترك إجراءات الإنشاء الكائن المُهيأ حديثًا في حالة تُحقق شرط الصنف الثابت. [ ب ]

على الرغم من أن إنشاء الكائنات ينطوي على بعض التفاصيل الدقيقة، [ 12 ] فإن إنشاء سمة بتصريح نموذجي x: Tكما هو موضح في تعليمات الإنشاء create x.makeيتكون من التسلسل التالي للخطوات:

  • أنشئ نسخة مباشرة جديدة من النوع T. [ ج ]
  • قم بتنفيذ إجراء الإنشاء makeعلى النسخة التي تم إنشاؤها حديثًا.
  • قم بربط الكائن الذي تم تهيئته حديثًا بالكيان x.

في المقتطف الأول أدناه، POINTتم تعريف الفئة. وتمت كتابة الإجراء makeبعد الكلمة المفتاحية feature.

تُعرّف الكلمة المفتاحية createقائمةً بالإجراءات التي يمكن استخدامها لتهيئة الكائنات. في هذه الحالة default_create، تتضمن القائمة إجراءً ذا تنفيذ فارغ موروث من الفئة ANY، والإجراء makeالمكتوب داخل الفئة.

إنشاء فئة POINT افتراضيًا ، ثم إنشاءميزةأنشئ ( قيمة_س : عدد حقيقي ؛ قيمة_ص : عدد حقيقي ) كرر س := قيمة_س ص ص := قيمة_ص نهايةس : حقيقي -- إحداثي سy : عدد حقيقي -- إحداثي Y ...

في المقتطف الثاني، يوجد صنف يمثل عميلًا POINTله تعريفات my_point_1من my_point_2النوع POINT.

في البرمجة الإجرائية، my_point_1يتم إنشاء المتغير كنقطة الأصل (0.0، 0.0). ولعدم تحديد إجراء إنشاء، يتم استخدام الإجراء default_createالموروث من الفئة . كان من الممكن كتابة هذا السطر بشكل مختلف . لا يمكن استخدام سوى الإجراءات المسماة كإجراءات إنشاء في التعليمات التي تحتوي على الكلمة المفتاحية. يلي ذلك تعليمات إنشاء لـ ، حيث يتم توفير القيم الأولية لإحداثيات 's. تقوم التعليمات الثالثة باستدعاء عادي للإجراء لإعادة تهيئة الكائن المرفق بـ بقيم مختلفة.ANYcreate my_point_1.default_createcreatemy_point_2my_point_2makemy_point_2

my_point_1 : نقطة my_point_2 : نقطة ...إنشاء my_point_1 إنشاء my_point_2 . إنشاء ( 3.0 ، 4.0 ) my_point_2 . إنشاء ( 5.0 ، 8.0 ) ...

فا#

في لغة F# ، يمكن أن يتضمن المُنشئ أي عبارات `private` letأو ` doprivate` مُعرّفة في فئة. letتُعرّف عبارات `private` الحقول الخاصة، بينما doتُنفّذ عبارات `private` التعليمات البرمجية. يمكن تعريف مُنشئات إضافية باستخدام newالكلمة المفتاحية `private`.

type MyClass (_ a : int , _ b : string ) = class // المُنشئ الأساسي let a = _ a let b = _ b do printfn "a = %i, b = %s" a b// مُنشئات إضافية new (_ a : int ) = MyClass (_ a , "" ) ثم printfn "تم إدخال مُعامل عدد صحيح"new (_ b : string ) = MyClass ( 0 , _ b ) then printfn "تم إدخال مُعامل سلسلة نصية"new () = MyClass ( 0 , "" ) then printfn "لم يتم إدخال أي مُعامل" end
// الكود موجود في مكان ما // إنشاء كائن باستخدام المُنشئ الأساسي let c1 = new MyClass ( 42 , "string" )// إنشاء كائن مع مُنشئات إضافية let c2 = new MyClass ( 42 ) let c3 = new MyClass ( "string" ) let c4 = MyClass () // الكلمة المفتاحية "new" اختيارية

جافا

في لغة جافا ، تختلف الدوال البانية عن الطرق الأخرى في أنها:

  • لا تحتوي الدوال البانية أبدًا على نوع إرجاع صريح.
  • لا يمكن استدعاء الدوال البانية بشكل مباشر (الكلمة المفتاحية " new" تستدعيها).
  • لا ينبغي أن تحتوي الدوال البانية على مُعدِّلات غير متعلقة بالوصول.

تقوم دوال البناء في لغة جافا بتنفيذ المهام التالية بالترتيب التالي:

  1. استدعِ المُنشئ الافتراضي للفئة الأصلية إذا لم يتم تعريف أي مُنشئ.
  2. قم بتهيئة متغيرات الأعضاء بالقيم المحددة.
  3. ينفذ جسم الدالة البانية.

تسمح لغة جافا للمستخدمين باستدعاء مُنشئ داخل مُنشئ آخر باستخدام this()الكلمة المفتاحية `name`. ولكن this()يجب أن يكون هذا هو السطر الأول. [ 13 ]

class X { public X () { // مُنشئ غير مُعامل this ( 1 ); // استدعاء المُنشئ System . out . println ( "استدعاء المُنشئ الافتراضي" ); }public X ( int a ) { // مُنشئ مُعامل System . out . println ( "استدعاء المُنشئ المُعامل" ); } }public class Example { public static void main ( String [] args ) { X x = new X (); } }

توفر لغة جافا إمكانية الوصول إلى مُنشئ الفئة الأساسيةsuper من خلال الكلمة المفتاحية.

class X { // تعريف متغيرات النسخة. private int data ;// تعريف الدالة البانية. public X () { this ( 1 ); }// تحميل زائد للدالة البانية public X ( int input ) { data = input ; // هذه عملية إسناد } }class Y extends X { private int data2 ;public Y () { super (); data2 = 1 ; }public Y ( int input1 , int input2 ) { super ( input1 ); data2 = input2 } }public class Example { public static void main ( String [] args ) { Y y = new Y ( 42 , 43 ); } }

يُطلق على الدالة البانية التي تأخذ صفرًا من الوسائط اسم الدالة البانية "بدون وسائط" أو "بدون وسائط". [ 14 ]

جافا سكريبت/تايب سكريبت

ابتداءً من إصدار ES6، أصبح لدى جافا سكريبت دوال إنشاء مباشرة مثل العديد من لغات البرمجة الأخرى. تُكتب هذه الدوال على هذا النحو.

class FooBar { constructor ( baz ) { this . baz = baz ; } }

يمكن إنشاء هذا على هذا النحو

const foo = new FooBar ( '7' );

كان المكافئ لهذا قبل ES6 هو إنشاء دالة تقوم بإنشاء كائن على هذا النحو

دالة FooBar ( baz ) { this . baz = baz ; }

يتم إنشاء هذا بنفس الطريقة المذكورة أعلاه.

سيكون المكافئ لهذا في لغة TypeScript هو:

class FooBar { baz : string ;constructor ( baz : string ) { this . baz = baz ; } }const foo : FooBar = new FooBar ( '7' );

أوبجكت باسكال

في لغة أوبجكت باسكال ، يُشبه المُنشئ طريقة المصنع . والفرق الوحيد في تركيبه النحوي عن الطرق العادية هو الكلمة المفتاحية `constructor` constructorالتي تسبق الاسم (بدلاً من `static` procedureأو `static` function). يمكن أن يحمل أي اسم، مع أن المتعارف عليه هو استخدام Create`static` كبادئة، كما في `static` CreateWithFormatting. إنشاء نسخة من فئة ما يُشبه استدعاء طريقة ثابتة لتلك الفئة: `static` TPerson.Create('Peter').

برنامج OopProgram ؛نوع TPerson = فئة خاصة FName : سلسلة نصية ؛ خاصية عامة Name : سلسلة نصية read FName ؛ مُنشئ Create ( AName : سلسلة نصية ) ؛ نهاية ؛constructor TPerson . Create ( AName : string ) ; begin FName := AName ; end ;var Person : TPerson ; begin Person := TPerson . Create ( 'Peter' ) ; // يُخصص نسخة من TPerson ثم يستدعي TPerson.Create مع المعامل AName = 'Peter' end .

أوكاميل

في لغة OCaml ، يوجد مُنشئ واحد. تُعرَّف المعاملات مباشرةً بعد اسم الصنف. يمكن استخدامها لتهيئة متغيرات النسخة، وهي متاحة في جميع أنحاء الصنف. initializerتسمح دالة مخفية مجهولة بتقييم تعبير ما فور إنشاء الكائن. [ 15 ]

class person first_name last_name = object val full_name = first_name ^ " " ^ last_nameinitializer print_endline ( "مرحباً، أنا " ^ الاسم_الكامل ^ "." )method get_last_name = last_name end ;;let alonzo = new person "Alonzo" "Church" in (*مرحباً، أنا ألونزو تشيرش.*)print_endline alonzo # get_last_name (*Church*)

PHP

في PHP الإصدار 5 والإصدارات الأحدث، الدالة البانية هي دالة تُسمى __construct()(لاحظ وجود شرطتين سفليتين)، ويتم newاستدعاؤها تلقائيًا بعد إنشاء الكائن. تُستخدم عادةً لإجراء عمليات التهيئة تلقائيًا، مثل تهيئة الخصائص. يمكن للدوال البانية أيضًا قبول وسائط، وفي هذه الحالة، عند newكتابة العبارة، يجب عليك أيضًا إرسال وسائط الدالة البانية للمعاملات. [ 2 ]

class Person { private string $name ;public function __construct ( string $name ) : void { $this -> name = $name ; }public function getName () : string { return $this -> name ; } }

في لغة PHP، يُسمح للفئة بتعريف دالة بناء واحدة كحد أقصى. وتُعدّ الدوال الثابتة، وفئات المصنع، ومعاملات البناء الاختيارية، من بين الطرق التي تُسهّل إنشاء كائنات من فئة PHP بطرق متعددة.

بيرل 5

في الإصدار الخامس من لغة بيرل ، تُعتبر الدوال البانية افتراضيًا دوالًا مصنعية ، أي دوالًا تُنشئ الكائن وتُرجعه، وهذا يعني تحديدًا إنشاء مرجع مُعتمد وإرجاعه. عادةً ما يكون الكائن مرجعًا إلى جدول تجزئة، مع أنه نادرًا ما تُستخدم مراجع لأنواع أخرى. جرت العادة على تسمية الدالة البانية الوحيدة بـ ` new` ، مع أنه يُسمح بتسميتها بغير ذلك، أو بوجود دوال بانية متعددة. على سبيل المثال، قد تحتوي فئة Person على دالة بانية باسم ` new` ، ودالة بانية أخرى باسم `new_from_file` تقرأ ملفًا لاستخراج سمات Person، ودالة بانية ثالثة باسم `new_from_person` تستخدم كائن Person آخر كقالب.

package Person ; # في لغة بيرل، تُسمى الدوال البانية 'new' وفقًا للاتفاقية. sub new { # يتم تمرير اسم الفئة ضمنيًا كوسيط صفري. my $class = shift ;# القيم الافتراضية للسمات، إن وجدت. my %defaults = ( foo => "bar" );# تهيئة السمات كمزيج من القيم الافتراضية والوسائط المُمرَّرة. my $self = { %defaults , @_ };# التحقق من الوسائط المطلوبة، وثوابت الفئة، وما إلى ذلك. إذا لم يتم تعريف السمة first_name في الكائن Person- > new ( ) ، فسيتم إيقاف البرنامج مع عرض رسالة خطأ تفيد بأن السمة first_name غير مطلوبة . وإذا لم يتم تعريف السمة last_name في الكائن Person- > new() ، فسيتم إيقاف البرنامج مع عرض رسالة خطأ تفيد بأن السمة last_name غير مطلوبة . وإذا تم تعريف السمة age في الكائن Person- > new ( ) وكانت قيمتها أقل من 18 ، فسيتم إيقاف البرنامج مع عرض رسالة خطأ تفيد بأن قيمة السمة age في الكائن Person->new() غير صالحة .# في لغة بيرل، يتم جعل كائن ينتمي إلى فئة باستخدام الأمر 'bless'. bless $self , $class ; return $self ; } 1 ;

بيرل 5 مع موس

في نظام كائنات Moose للغة Perl، يمكن حذف معظم هذه التعليمات البرمجية المتكررة، حيث يتم إنشاء كائن جديد افتراضيًا ، ويمكن تحديد السمات، وما إذا كان بالإمكان تعيينها أو إعادة تعيينها أو ما إذا كانت مطلوبة. بالإضافة إلى ذلك، يمكن تضمين أي وظائف إضافية للمنشئ في دالة BUILD التي سيستدعيها المنشئ الذي تم إنشاؤه بواسطة Moose، بعد التحقق من الوسائط. ويمكن تحديد دالة BUILDARGS للتعامل مع وسائط المنشئ التي ليست على شكل hashref / key => value.

حزمة Person ؛ # تمكين إنشاء الكائنات على نمط Moose استخدام Moose ؛# لا يمكن تحديد الاسم الأول (نص) إلا عند إنشاء الكائن ('ro'). has first_name => ( is => 'ro' , isa => 'Str' , required => 1 ); # لا يمكن تحديد اسم العائلة (نص) إلا عند إنشاء الكائن ('ro'). has last_name => ( is => 'ro' , isa => 'Str' , required => 1 ); # يمكن تعديل العمر (عدد صحيح) بعد إنشاء الكائن ('rw')، وليس من الضروري # تمريره إلى المُنشئ. كما يُنشئ دالة 'has_age' التي تُرجع # القيمة true إذا تم تحديد العمر. has age => ( is => 'rw' , isa => 'Int' , predicate => 'has_age' );# التحقق من المتطلبات المخصصة sub BUILD { my $self = shift ; if ( $self -> has_age && $self -> age < 18 ) { # ممنوع دخول من هم دون سن 18 die "ممنوع دخول من هم دون سن 18" ; } } 1 ;

في كلتا الحالتين، يتم إنشاء فئة الشخص على النحو التالي:

استخدم Person ؛ my $p = Person- > new ( first_name => 'Sam' , last_name => 'Ashe' , age => 42 );

بايثون

في لغة بايثون ، تُعرَّف الدوال البانية بواسطة إحدى أو كلتا الطريقتين `constructor` و`constructor` __new__. __init__يتم إنشاء نسخة جديدة من الصنف باستدعاء الصنف كما لو كان دالة، والتي بدورها تستدعي الطريقتين `constructor` __new__و` __init__constructor`. إذا لم يتم تعريف دالة بانية في الصنف، فسيتم استدعاء الدالة التالية الموجودة في ترتيب استدعاء الدوال للصنف. [ 16 ]

في الحالة النموذجية، __init__يكفي تعريف الطريقة فقط. (الاستثناء الأكثر شيوعًا هو بالنسبة للكائنات غير القابلة للتغيير).

class ExampleClass : def __new__ ( cls : type , value : int ) -> 'ExampleClass' : print ( "إنشاء نسخة جديدة..." ) # استدعاء مُنشئ الفئة الأصلية لإنشاء النسخة. instance : 'ExampleClass' = super ( ExampleClass , cls ) . __new__ ( cls ) return instancedef __init__ ( self , value : int ) -> None : print ( " جاري تهيئة الكائن... " ) self.payload : int = valueإذا كان __name__ يساوي " __main__ " : مثال_المثيل : فئة_المثيل = فئة_المثيل ( 42 ) طباعة ( مثال_المثيل.الحمولة )

هذا يطبع:

إنشاء نسخة جديدة... جارٍ تهيئة النسخة... 42 

عادةً ما تعمل الأصناف كمصانع لإنشاء نسخ جديدة منها، أي أن الصنف عبارة عن كائن قابل للاستدعاء (مثل دالة)، ويكون الاستدعاء هو المُنشئ، واستدعاء الصنف يُعيد نسخة منه. ومع ذلك، __new__يُسمح للدالة بإرجاع شيء آخر غير نسخة من الصنف لأغراض خاصة. في هذه الحالة، __init__لا يتم استدعاء الدالة. [ 16 ]

راكو

في راكو ، يمكن الاستغناء عن المزيد من التعليمات البرمجية المتكررة، نظرًا لوجود دالة إنشاء افتراضية موروثة، وإمكانية تحديد السمات، وتحديد ما إذا كان بالإمكان تعيينها أو إعادة تعيينها أو ما إذا كانت مطلوبة. بالإضافة إلى ذلك، يمكن تضمين أي وظائف إضافية للمنشئ في دالة BUILD التي سيتم استدعاؤها للسماح بالتهيئة المخصصة. كما يمكن تحديد دالة TWEAK لمعالجة أي سمات تمت تهيئتها (ضمنياً) مسبقاً.

class Person { has Str $.first-name is required ; # لا يمكن تعيين الاسم الأول (سلسلة نصية) إلا عند # وقت الإنشاء (النقطة تعني "عام"). has Str $.last-name is required ; # لا يمكن تعيين اسم العائلة (سلسلة نصية) إلا عند # وقت الإنشاء (علامة ! تعني "خاص"). has Int $.age is rw ; # يمكن تعديل العمر (عدد صحيح) بعد # الإنشاء ('rw')، وهو غير مطلوب # أثناء إنشاء الكائن.# أنشئ دالة باسم 'full-name' تُعيد الاسم الكامل للشخص. # يمكن الوصول إلى هذه الدالة من خارج الفئة. method full-name { $!first-name . tc ~ " " ~ $!last-name . tc } # أنشئ دالة 'has-age' تُرجع القيمة true إذا تم تحديد العمر. # تُستخدم هذه الدالة داخل الفئة فقط، لذا تم تعريفها على أنها "خاصة" # بإضافة ! إلى اسمها! method ! has - age { self.age.defined }# التحقق من متطلبات مخصصة طريقة TWEAK { إذا كان self ! لديه عمر && $!العمر < 18 { # لا يوجد شخص أقل من 18 عامًا die "لا يوجد شخص أقل من 18 عامًا" ; } } } 

يتم إنشاء مثيل لفئة الشخص على النحو التالي:

my $p0 = Person.new ( first -name => 'Sam' , last-name => 'Ashe' , age => 42 ); my $p1 = Person.new ( first -name => ' grace' , last-name => ' hopper' ); say $ p1.full -name (); # الناتج: «Grace Hopper␤»

بدلاً من ذلك، يمكن تحديد المعلمات المسماة باستخدام صيغة النقطتين في لغة بيرل 6:

my $p0 = Person.new ( : first -name <Sam> , : last-name <Ashe> , : age ( 42 )); my $p1 = Person.new ( : first-name <Grace> , : last-name <Hopper> ); 

وإذا كنت قد قمت بإعداد متغيرات بأسماء مطابقة للمعاملات المسماة، فيمكنك استخدام اختصار يستخدم اسم المتغير للمعامل المسمى:

my $first-name = "Sam" ; my $last-name = "Ashe" ; my $age = 42 ; my $p0 = Person . new ( : $first-name , : $last-name , : $age ); 

روبي

في لغة روبي ، يتم إنشاء الدوال البانية عن طريق تعريف دالة تسمى initialize. يتم تنفيذ هذه الدالة لتهيئة كل نسخة جديدة.

irb(main):001:0> class ExampleClass irb(main):002:1> def initialize irb(main):003:2> puts "Hello there" irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> ExampleClass . new Hello there => #<ExampleClass:0x007fb3f4299118>

الصدأ

لا تحتوي لغة Rust على دوال إنشاء بالمعنى المتعارف عليه في البرمجة كائنية التوجه، ولكن غالبًا ما تحتوي الهياكل على new()دالة تعمل أساسًا كدالة إنشاء. ويُشار عادةً إلى نوع القيمة المُعادة بـ Self.

struct Point { x : i32 , y : i32 , }impl Point { pub fn new ( x : i32 , y : i32 ) -> Self { Point { x , y } } }fn main () { let p : Point = Point :: new ( 10 , 20 ); println! ( "النقطة عند ({}, {})" , p . x , p . y ); }

فيجوال بيسك دوت نت

في Visual Basic .NET ، تستخدم الدوال البانية تعريفًا للطريقة باسم " New".

فئة Foobar، بيانات خاصة strData من نوع سلسلة نصية' Constructor Public Sub New ( ByVal someParam As String ) strData = someParam End Sub End Class
'كود في مكان آخر ' إنشاء كائن باستخدام المُنشئ أعلاه Dim foo As New Foobar ( ".NET" )

انظر أيضاً

ملحوظات

  1. تُصنف إجراءات إيفلإما كإجراءات أو دوال . الإجراءات لا تحتوي على نوع إرجاع. أما الدوال فلها نوع إرجاع دائمًا.
  2. نظرًا لأنه يجب استيفاء شرط الفئة الموروثة، فلا يوجد استدعاء إلزامي لمنشئات الآباء.
  3. يتطلب معيار Eiffel تهيئة الحقول عند الوصول الأول، لذلك ليس من الضروري إجراء تهيئة افتراضية للحقول أثناء إنشاء الكائن.

مراجع

  1. إنشاء، تهيئة، وتخصيص ، من دليل مرجع كريستال
  2. 1 2 3 المُنشئات والمُدمِّرات ، من وثائق PHP على الإنترنت
  3. نموذج البيانات ، من وثائق بايثون على الإنترنت
  4. https://stackoverflow.com/questions/1242830/constructor-initialization-list-evaluation-order المُنشئ
  5. "تعبيرات جديدة من نوع الهدف" . learn.microsoft.com . مايكروسوفت ليرن. 23 يونيو 2023.
  6. 12 البحاري ، يوسف. C#10 باختصار . أورايلي. رقم ISBN 978-1-098-12195-2.
  7. "مغامرات رائعة في البرمجة" . إريك ليبرت. 2013-02-06 . تم الاطلاع عليه بتاريخ 2014-04-05 .
  8. خبير .NET 2.0 IL المجمع . أصحافة. 2006-01-01. رقم ISBN 9781430202233تم الاطلاع عليه بتاريخ 2014-04-05 .
  9. "قم بتنزيل وثائق Visual Studio 2005 القديمة من مركز تنزيل Microsoft الرسمي" . متجر Microsoft - مركز التنزيل .
  10. سكيت، جون (23 مارس 2019). لغة سي شارب بتفصيل . مانينغ. ISBN 978-1617294532.
  11. مكون CF
  12. "وثيقة مواصفات إيفل ISO/ECMA" .
  13. "تفاصيل حول المُنشئ في جافا" .
  14. "توفير دوال البناء لفئاتك" . شركة أوراكل. 2013. تم الاطلاع عليه بتاريخ 20-12-2013 .
  15. "OCaml - دليل OCaml" . ocaml.org .
  16. 1 2 "3. نموذج البيانات" . وثائق بايثون .