Property (programming)
This article needs additional citations for verification.(January 2022) |
A property, in some object-orientedprogramming languages, is a special sort of class member, intermediate in functionality between a field (or data member) and a method. The syntax for reading and writing of properties is like for fields, but property reads and writes are (usually) translated to 'getter' and 'setter' method calls. The field-like syntax is easier to read and write than many method calls,[citation needed] yet the interposition of method calls "under the hood" allows for data validation, active updating (e.g., of GUI elements), or implementation of what may be called "read-only fields".
Support in languages
[edit]Programming languages that support properties include ActionScript 3, C#, D, Delphi/Free Pascal, eC, F#, Kotlin, JavaScript, Objective-C 2.0, Python, Scala, Swift, Lua, and Visual Basic.
Some object-oriented languages, such as Java and C++, do not support properties, requiring the programmer to define a pair of accessor and mutator methods instead.[1][citation needed]
Oberon-2 provides an alternative mechanism using object variable visibility flags.[citation needed]
Other languages designed for the Java Virtual Machine, such as Groovy, natively support properties.
While C++ does not have first class properties, they can be emulated with operator overloading.[2]
Also note that some C++ compilers support first class properties as language extensions.[citation needed]
- In Microsoft Visual Studio,[3]GCC, and llvm/clang,[4] the
__declspec(property)
creates properties similar to C#. - Borland C++ and Borland/CodeGear/Embarcadero C++Builder use the
__property
keyword.[5]
In many object oriented languages properties are implemented as a pair of accessor/mutator methods, but accessed using the same syntax as for public fields. Omitting a method from the pair yields a read-only or an uncommon write-only property.
In some languages with no built-in support for properties, a similar construct can be implemented as a single method that either returns or changes the underlying data, depending on the context of its invocation. Such techniques are used e.g. in Perl. [citation needed]
Some languages (Ruby, Smalltalk) achieve property-like syntax using normal methods, sometimes with a limited amount of syntactic sugar.
Syntax variants
[edit]Some languages follow well-established syntax conventions for formally specifying and utilizing properties and methods.
Among these conventions:
- Dot notation
- Bracket notation
Dot notation
[edit]The following example demonstrates dot notation in JavaScript.
document.createElement('pre');
Bracket notation
[edit]The following example demonstrates bracket notation in JavaScript.
document['createElement']('pre');
Example syntax
[edit]C#
[edit]classPen{privateintcolor;// private field// public propertypublicintColor{get{returnthis.color;}set{if(value>0){this.color=value;}}}}
// accessing:Penpen=newPen();intcolor_tmp=0;// ...pen.Color=17;color_tmp=pen.Color;// ...pen.Color=~pen.Color;// bitwise complement ...// another silly example:pen.Color+=1;// a lot clearer than "pen.set_Color(pen.get_Color() + 1)"!
Recent C# versions also allow "auto-implemented properties" where the backing field for the property is generated by the compiler during compilation. This means that the property must have a setter. However, it can be private.
classShape{publicintHeight{get;set;}publicintWidth{get;privateset;}}
C++
[edit]![]() | This article may be confusing or unclear to readers.(October 2016) |
C++ does not have first class properties, but there exist several ways to emulate properties to a limited degree. Two of which follow:
Using Standard C++
[edit]#include<iostream>template<typenameT>classproperty{Tvalue;public:T&operator=(constT&i){returnvalue=i;}// This template class member function template serves the purpose to make// typing more strict. Assignment to this is only possible with exact identical types.// The reason why it will cause an error is temporary variable created while implicit type conversion in reference initialization.template<typenameT2>T2&operator=(constT2&i){T2&guard=value;throwguard;// Never reached.}// Implicit conversion back to T. operatorTconst&()const{returnvalue;}};structFoo{// Properties using unnamed classes.class{intvalue;public:int&operator=(constint&i){returnvalue=i;}operatorint()const{returnvalue;}}alpha;class{floatvalue;public:float&operator=(constfloat&f){returnvalue=f;}operatorfloat()const{returnvalue;}}bravo;};structBar{// Using the property<>-template.property<bool>alpha;property<unsignedint>bravo;};intmain(){Foofoo;foo.alpha=5;foo.bravo=5.132f;Barbar;bar.alpha=true;bar.bravo=true;// This line will yield a compile time error// due to the guard template member function.::std::cout<<foo.alpha<<", "<<foo.bravo<<", "<<bar.alpha<<", "<<bar.bravo<<::std::endl;return0;}
Also see Stack Overflow for a more detailed example.
C++, Microsoft, GCC, LLVM/clang and C++Builder-specific
[edit]An example taken from the MSDN documentation page.
// declspec_property.cppstructS{inti;voidputprop(intj){i=j;}intgetprop(){returni;}__declspec(property(get=getprop,put=putprop))intthe_prop;};intmain(){Ss;s.the_prop=5;returns.the_prop;}
D
[edit]classPen{privateintm_color;// private field// public get propertypublicintcolor(){returnm_color;}// public set propertypublicvoidcolor(intvalue){m_color=value;}}
autopen=newPen;pen.color=~pen.color;// bitwise complement// the set property can also be used in expressions, just like regular assignmentinttheColor=(pen.color=0xFF0000);
In D version 2, each property accessor or mutator must be marked with @property:
classPen{privateintm_color;// private field// public get property@propertypublicintcolor(){returnm_color;}// public set property@propertypublicvoidcolor(intvalue){m_color=value;}}
Delphi/Free Pascal
[edit]typeTPen=classprivateFColor:TColor;functionGetColor:TColor;procedureSetColor(constAValue:TColor);publicpropertyColor:IntegerreadGetColorwriteSetColor;end;functionTPen.GetColor:TColor;beginResult:=FColor;end;procedureTPen.SetColor(constAValue:TColor);beginifFColor<>AValuethenFColor:=AValue;end;
// accessing:varPen:TPen;// ...Pen.Color:=notPen.Color;(*Delphi and Free Pascal also support a 'direct field' syntax -property Color: TColor read FColor write SetColor;orproperty Color: TColor read GetColor write FColor;where the compiler generates the exact same code as for reading and writinga field. This offers the efficiency of a field, with the safety of a property.(You can't get a pointer to the property, and you can always replace the memberaccess with a method call.)*)
eC
[edit]classPen{// private data memberColorcolor;public:// public propertypropertyColorcolor{get{returncolor;}set{color=value;}}}PenblackPen{color=black};PenwhitePen{color=white};Penpen3{color={30,80,120}};Penpen4{color=ColorHSV{90,20,40}};
F#
[edit]typePen()=classletmutable_color=0memberthis.Colorwithget()=_colorandsetvalue=_color<-valueend
letpen=newPen()pen.Color<-~~~pen.Color
JavaScript
[edit]functionPen(){this._color=0;}// Add the property to the Pen type itself, can also// be set on the instance individuallyObject.defineProperties(Pen.prototype,{color:{get:function(){returnthis._color;},set:function(value){this._color=value;}}});
varpen=newPen();pen.color=~pen.color;// bitwise complementpen.color+=1;// Add one
ActionScript 3.0
[edit]package{publicclassPen{privatevar_color:uint=0;publicfunctiongetcolor():uint{return_color;}publicfunctionsetcolor(value:uint):void{_color=value;}}}
varpen:Pen=newPen();pen.color=~pen.color;// bitwise complementpen.color+=1;// add one
Objective-C 2.0
[edit]@interfacePen : NSObject@property(copy)NSColor*colour;// The "copy" attribute causes the object's copy to be// retained, instead of the original.@end@implementationPen@synthesizecolour;// Compiler directive to synthesise accessor methods.// It can be left behind in Xcode 4.5 and later.@end
The above example could be used in an arbitrary method like this:
Pen*pen=[[Penalloc]init];pen.colour=[NSColorblackColor];floatred=pen.colour.redComponent;[pen.colourdrawSwatchInRect:NSMakeRect(0,0,100,100)];
PHP
[edit]classPen{privateint$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;}returnnull;}}
$p=newPen();$p->color=~$p->color;// Bitwise complementecho$p->color;
Python
[edit]Properties only work correctly for new-style classes (classes that have object
as a superclass), and are only available in Python 2.2 and newer (see the relevant section of the tutorial Unifying types and classes in Python 2.2). Python 2.6 added a new syntax involving decorators for defining properties.
classPen:def__init__(self)->None:self._color=0# "private" variable@propertydefcolor(self):returnself._color@color.setterdefcolor(self,color):self._color=color
pen=Pen()# Accessing:pen.color=~pen.color# Bitwise complement ...
Ruby
[edit]classPendefinitialize@color=0end# Defines a getter for the @color fielddefcolor@colorend# Defines a setter for the @color fielddefcolor=(value)@color=valueendendpen=Pen.newpen.color=~pen.color# Bitwise complement
Ruby also provides automatic getter/setter synthesizers defined as instance methods of Class.
classPenattr_reader:brand# Generates a getter for @brand (Read-Only)attr_writer:size# Generates a setter for @size (Write-Only)attr_accessor:color# Generates both a getter and setter for @color (Read/Write)definitialize@color=0# Within the object, we can access the instance variable directly@brand="Penbrand"@size=0.7# But we could also use the setter method defined by the attr_accessor Class instance methodendendpen=Pen.newputspen.brand# Accesses the pen brand through the generated getterpen.size=0.5# Updates the size field of the pen through the generated setterpen.color=~pen.color
Visual Basic
[edit]Visual Basic (.NET 2003–2010)
[edit]PublicClassPenPrivate_colorAsInteger' Private fieldPublicPropertyColor()AsInteger' Public propertyGetReturn_colorEndGetSet(ByValvalueAsInteger)_color=valueEndSetEndPropertyEndClass
' Create Pen class instanceDimpenAsNewPen()' Set valuepen.Color=1' Get valueDimcolorAsInt32=pen.Color
Visual Basic (only .NET 2010)
[edit]PublicClassPenPublicPropertyColor()AsInteger' Public propertyEndClass
' Create Pen class instanceDimpenAsNewPen()' Set valuepen.Color=1' Get valueDimcolorAsInt32=pen.Color
Visual Basic 6
[edit]' in a class named clsPenPrivatem_ColorAsLongPublicPropertyGetColor()AsLongColor=m_ColorEndPropertyPublicPropertyLetColor(ByValRHSAsLong)m_Color=RHSEndProperty
' accessing:DimpenAsNewclsPen' ...pen.Color=Notpen.Color
See also
[edit]- Attribute (computing)
- Bound property
- Field (computer science)
- Indexer (programming)
- Method (computer programming)
- Mutator method
- Uniform access principle
References
[edit]- ^"Accessors And Mutators In Java". C# Corner - Community of Software and Data Developers. Retrieved 5 January 2022.
- ^"Portability of Native C++ properties". Stack Overflow. Stack Overflow. Retrieved 5 January 2022.
- ^"property (C++)". Microsoft technical documentation. Microsoft. Retrieved 5 January 2022.
- ^"clang::MSPropertyDecl Class Reference". Clang: a C language family frontend for LLVM. Retrieved 5 January 2022.
- ^"__property Keyword Extension". Embarcadero/IDERA Documentation Wiki. Retrieved 5 January 2022.