الملكية (البرمجة)

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

الدعم باللغات

تشمل لغات البرمجة التي تدعم الخصائص C# و D و ECMAScript ( ActionScript 3 و JavaScript ) و eC و F# و Kotlin و Object Pascal ( Delphi و Free Pascal ) و Objective-C 2.0 و Python و Scala و Swift و Lua و Visual Basic .

بعض لغات البرمجة الكائنية، مثل جافا وسي ++ ، لا تدعم الخصائص، مما يتطلب من المبرمج تعريف زوج من دوال الوصول والتعديل بدلاً من ذلك. [ 1 ]

يوفر Oberon-2 آلية بديلة باستخدام علامات رؤية متغيرات الكائن.

تدعم لغات أخرى مصممة لآلة جافا الافتراضية ، مثل Groovy ، الخصائص بشكل أصلي.

على الرغم من أن لغة C++ لا تحتوي على خصائص من الدرجة الأولى، إلا أنه يمكن محاكاتها باستخدام تحميل المعاملات الزائد . [ 2 ]

تدعم بعض مترجمات لغة C++ خصائص الدرجة الأولى كامتدادات للغة.

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

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

تحقق بعض اللغات ( مثل Ruby و Smalltalk ) بنية تشبه بنية الخصائص باستخدام الطرق العادية، وأحيانًا بكمية محدودة من التحسين النحوي .

متغيرات بناء الجملة

تتبع بعض اللغات اصطلاحات نحوية راسخة لتحديد واستخدام الخصائص والأساليب بشكل رسمي.

من بين هذه الاتفاقيات:

  • تدوين النقطة
  • تدوين الأقواس

تدوين النقطة

يوضح المثال التالي طريقة استخدام النقطة في جافا سكريبت.

document.createElement ( "pre " ) ;

تدوين الأقواس

يوضح المثال التالي طريقة استخدام الأقواس في جافا سكريبت.

document [ "createElement" ]( "pre" );

مثال على بناء الجملة

سي شارب

class Pen { private int color ; // حقل خاص // خاصية عامة public int Color { get { return this . color ; } set { if ( value > 0 ) { this . color = value ; } } } }
// الوصول: Pen pen = new ( ) ; int colorTmp = 0 ; // ... pen.Color = 17 ; colorTmp = pen.Color ; // ... pen.Color = ~ pen.Color ; // المتمم الثنائي ...// مثال آخر سخيف: pen.Color += 1 ; // أوضح بكثير من "pen.set_Color(pen.get_Color() + 1)" !

تسمح إصدارات C# الحديثة أيضًا بـ "الخصائص المُنفذة تلقائيًا"، حيث يُنشئ المُصرّف حقل البيانات الخاص بالخاصية أثناء عملية الترجمة. هذا يعني أن الخاصية يجب أن تحتوي على دالة تعيين (setter). مع ذلك، يمكن أن تكون هذه الخاصية خاصة (private).

class Shape { public int Height { get ; set ; } public int Width { get ; private set ; } }

لغة سي++

لا تمتلك لغة C++ خصائص من الدرجة الأولى، ولكن توجد عدة طرق لمحاكاة الخصائص بدرجة محدودة. اثنتان منها كالتالي:

باستخدام لغة C++ القياسية

استيراد std ؛باستخدام std :: same_as ؛template < typename T > class Property { T value ; public : // تأكد من أن T و T2 من نفس النوع template < typename U > requires same_as < T , U > T & operator = ( const U & i ) { value = i ; return * this ; }// تحويل ضمني إلى T. operator T const & () const { return value ; } };struct Foo { // خصائص باستخدام فئات غير مسماة. class { private : int value ; public : int & operator = ( const int & i ) { return value = i ; } int operator int () const { return value ; } } alpha ;class { private : float value ; public : float & operator = ( const float & f ) { return value = f ; } float operator float () const { return value ; } } bravo ; };struct Bar { // باستخدام قالب Property<>. Property <bool> alpha ; Property < unsigned int > bravo ; } ;int main ( int argc , char * argv []) { Foo foo ; foo . alpha = 5 ; foo . bravo = 5.132f ;bar bar ; bar.alpha = true ; bar.bravo = true ; // سيؤدي هذا السطر إلى خطأ في وقت الترجمة بسبب دالة العضو الخاصة بقالب الحماية. std :: println ( " { } , { } , { }, { } " , foo.alpha , foo.bravo , bar.alpha , bar.bravo ) ; return 0 ; }

C++، مايكروسوفت، GCC، LLVM/clang، وC++Builder-specific

مثال مقتبس من صفحة التوثيق الخاصة بـ MSDN .

// declspec_property.cpp struct Integer { int value ;void setValue ( int j ) noexcept { value = j ; }[[ nodiscard ]] int getValue () const noexcept { return i ; }__declspec ( property ( get = getValue , put = setValue )) int prop ; };int main () { Integer s ; s . prop = 5 ; return 0 ; }

د

class Pen { private int myColor ; // حقل خاص // خاصية عامة للقراءة public int color () { return myColor ; } // خاصية عامة للتعيين public void color ( int value ) { myColor = value ; } }
Pen pen = new Pen ; pen.color = ~ pen.color ; // المتمم الثنائي// يمكن أيضًا استخدام خاصية المجموعة في التعبيرات، تمامًا مثل التعيين العادي int theColor = ( pen . color = 0xFF0000 );

في الإصدار الثاني من D، يجب وضع علامة @property على كل خاصية من خصائص الوصول أو التعديل:

class Pen { private int myColor ; // حقل خاص // public get property @property public int color () { return myColor ; } // public set property @property public void color ( int value ) { myColor = value ; } }

eC

class Pen { // عضو بيانات خاص Color color ; public : // خاصية عامة property Color color { get { return color ; } set { color = value ; } } } Pen blackPen { color = black }; Pen whitePen { color = white }; Pen pen3 { color = { 30 , 80 , 120 } }; Pen pen4 { color = ColorHSV { 90 , 20 , 40 } };

فا#

نوع Pen ( ) = فئة let mutable_color = 0عضو في هذا . لون باستخدام get () = _ color و set value = _ color <- value end
let pen = new Pen ( ) pen.Color < - ~~~ pen.Color

جافا سكريبت

دالة Pen () { this._color = 0 ; } // أضف الخاصية إلى نوع Pen نفسه، ويمكن أيضًا // تعيينها على الكائن بشكل فردي Object.defineProperties ( Pen.prototype , { color : { get : function ( ) { return this._color ; } , set : function ( value ) { this._color = value ; } } } ) ;
var pen = new Pen ( ); pen.color = ~ pen.color ; // المكمل الثنائي pen.color + = 1 ; // أضف واحدًا

ActionScript 3.0

package { public class Pen { private var _color : uint = 0 ; public function get color (): uint { return _color ; } public function set color ( value : uint ): void { _color = value ; } } }
var pen : Pen = new Pen ( ); pen.color = ~ pen.color ; // المكمل الثنائي pen.color + = 1 ; // أضف واحدًا

أوبجكت باسكال (دلفي، فري باسكال)

نوع TPen = فئة خاصة FColor : TColor ; دالة GetColor : TColor ; إجراء SetColor ( const AValue : TColor ) ; خاصية عامة Color : عدد صحيح قراءة GetColor كتابة SetColor ; نهاية ;دالة TPen.GetColor : TColor ؛ بداية النتيجة : = FColor ؛ نهاية ؛الإجراء TPen . SetColor ( const AValue : TColor ) ; ابدأ إذا كان FColor <> AValue ثم FColor := AValue ; نهاية ؛
// الوصول إلى: var Pen : TPen ; // ... Pen . Color := not Pen . Color ;(* يدعم كل من دلفي وفري باسكال أيضًا صيغة "الحقل المباشر" -خاصية اللون: TColor للقراءة FColor للكتابة SetColor؛أوخاصية اللون: TColor للقراءة GetColor والكتابة FColor؛حيث يُولّد المُصرّف نفس الشيفرة تمامًا كما هو الحال عند قراءة وكتابة حقل. وهذا يُوفّر كفاءة الحقل مع أمان الخاصية. (لا يُمكن للمؤشر الوصول إلى الخاصية، ويمكن دائمًا استبدال الوصول إلى العضو باستدعاء دالة.) *)

أوبجكتيف-سي 2.0

@interface Pen : NSObject @property ( copy ) NSColor * colour ; // خاصية "copy" تجعل نسخة الكائن // تُحتفظ بها، بدلاً من الأصل. @end@implementation Pen @synthesize colour ; // توجيه للمُصرّف لتوليد دوال الوصول. // يمكن الاستغناء عنه في Xcode 4.5 والإصدارات الأحدث. @end

يمكن استخدام المثال أعلاه بطريقة عشوائية مثل هذه:

Pen * pen = [[ Pen alloc ] init ]; pen . colour = [ NSColor blackColor ]; float red = pen . colour . redComponent ; [ pen . colour drawSwatchInRect : NSMakeRect ( 0 , 0 , 100 , 100 )];

PHP

class Pen { private int $color = 1 ;function __set ( $property , $value ) { if ( property_exists ( $this , $property )) { $this -> $property = $value ; } }function __get ( $property ) { if ( property_exists ( $this , $property )) { return $this -> $property ; } return null ; } }
$p = new Pen (); $p- > color = ~ $p- > color ; // المكمل الثنائي echo $p- > color ;

بايثون

لا تعمل الخصائص بشكل صحيح إلا مع الفئات الجديدة (الفئات التي ترث objectمن فئة أساسية )، وهي متاحة فقط في بايثون 2.2 والإصدارات الأحدث (راجع القسم ذي الصلة من الدليل التعليمي " توحيد الأنواع والفئات في بايثون 2.2 "). أضافت بايثون 2.6 صيغة جديدة تتضمن استخدام المُزخرفات لتعريف الخصائص.

class Pen : _color : int متغير "خاص"def __init__ ( self ) -> None : self . _color = 0@property def color ( self ) -> int : return self . _color@ color.setter def color ( self , color : int ) - > None : self._color = color
قلم : قلم = قلم () # الوصول إلى: قلم . لون = ~ قلم . لون # المتمم الثنائي ...

روبي

class Pen def initialize @color = 0 end # يُعرّف دالة جلب لحقل @color def color @color end# يُعرّف دالة تعيين لحقل @color def color= ( value ) @color = value end endقلم = قلم جديد قلم . لون = ~ قلم . لون # المكمل الثنائي

توفر لغة روبي أيضًا مُركِّبات تلقائية لدوال الوصول والتعديل مُعرَّفة كطرق مثيل للفئة.

class Pen attr_reader :brand # يُنشئ دالة جلب لـ @brand (للقراءة فقط) attr_writer :size # يُنشئ دالة تعيين لـ @size (للكتابة فقط) attr_accessor :color # يُنشئ دالة جلب وتعيين لـ @color (للقراءة والكتابة)def initialize @color = 0 # داخل الكائن ، يمكننا الوصول إلى متغير النسخة مباشرةً @brand = "Penbrand" @size = 0.7 # ولكن يمكننا أيضًا استخدام دالة التعيين المُعرَّفة بواسطة دالة نسخة الفئة attr_accessor end endpen = Pen.new puts pen.brand # الوصول إلى ماركة القلم من خلال الدالة getter المُنشأة pen.size = 0.5 # تحديث حقل حجم القلم من خلال الدالة setter المُنشأة pen.color = ~ pen.color

فيجوال بيسك

فيجوال بيسك (.NET 2003–2010)

Public Class Pen Private _color As Integer ' حقل خاصخاصية عامة Color () كعدد صحيح ' خاصية عامة Get Return _color End Get Set ( ByVal value As Integer ) _color = value End Set End Propertyنهاية الفئة
إنشاء نسخة من فئة القلم Dim pen As New Pen ()'ضبط قيمة القلم . اللون = 1احصل على القيمة Dim color As Int32 = pen . Color

فيجوال بيسك (فقط .NET 2010)

قلم الصف العامخاصية عامة اللون () كعدد صحيح ' خاصية عامةنهاية الفئة
إنشاء نسخة من فئة القلم Dim pen As New Pen ()'ضبط قيمة القلم . اللون = 1احصل على القيمة Dim color As Int32 = pen . Color

فيجوال بيسك 6

في فئة تسمى clsPen، متغير خاص m_Color من نوع Longخاصية عامة Get Color () As Long Color = m_Color End Propertyخاصية عامة Let Color ( ByVal RHS As Long ) m_Color = RHS End Property
' الوصول : Dim pen As New clsPen ' ... pen.Color = Not pen.Color

انظر أيضاً

مراجع

  1. "الوصول والتعديل في جافا" . ركن سي شارب - مجتمع مطوري البرامج والبيانات . تم الاطلاع عليه في 5 يناير 2022 .
  2. "قابلية نقل خصائص لغة C++ الأصلية" . ستاك أوفرفلو . ستاك أوفرفلو . تم الاطلاع عليه في 5 يناير 2022 .
  3. "الخاصية (C++)" . وثائق مايكروسوفت التقنية . مايكروسوفت . تم الاطلاع عليه بتاريخ 5 يناير 2022 .
  4. "مرجع فئة clang::MSPropertyDecl" . Clang: واجهة أمامية لعائلة لغات C لـ LLVM . تم الاطلاع عليه بتاريخ 5 يناير 2022 .
  5. "امتداد الكلمة المفتاحية __property" . ويكي توثيق Embarcadero/IDERA . تم الاطلاع عليه بتاريخ 5 يناير 2022 .