Property (programming)

A property, in some object-oriented programming 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 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]
class Pen  {     private int color; // private field          // public property     public int Color      {           get         {             return this.color;         }         set          {             if (value > 0) {                 this.color = value;             }         }     } } 
// accessing: Pen pen = new Pen(); int color_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.

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

C++

[edit]

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 <typename T> class property {         T value;     public:         T & operator = (const T &i) {             return value = 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 <typename T2> T2 & operator = (const T2 &i) {             T2 &guard = value;             throw guard; // Never reached.         }          // Implicit conversion back to T.          operator T const & () const {             return value;         } };  struct Foo {     // Properties using unnamed classes.     class {             int value;         public:             int & operator = (const int &i) { return value = i; }             operator int () const { return value; }     } alpha;      class {             float value;         public:             float & operator = (const float &f) { return value = f; }             operator float () const { return value; }     } bravo; };  struct Bar {     // Using the property<>-template.     property <bool> alpha;     property <unsigned int> bravo; };  int main () {     Foo foo;     foo.alpha = 5;     foo.bravo = 5.132f;      Bar bar;     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;     return 0; } 

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.cpp struct S {    int i;    void putprop(int j)    {        i = j;    }     int getprop()    {       return i;    }     __declspec(property(get = getprop, put = putprop)) int the_prop; };  int main() {    S s;    s.the_prop = 5;    return s.the_prop; } 

D

[edit]
class Pen {     private int m_color; // private field          // public get property     public int color () {         return m_color;     }          // public set property     public void color (int value) {          m_color = value;     } } 
auto pen = new Pen; pen.color = ~pen.color; // bitwise complement  // the set property can also be used in expressions, just like regular assignment int theColor = (pen.color = 0xFF0000); 

In D version 2, each property accessor or mutator must be marked with @property:

class Pen {     private int m_color; // private field          // public get property     @property public int color () {         return m_color;     }          // public set property     @property public void color (int value) {         m_color = value;     } } 

Delphi/Free Pascal

[edit]
type TPen = class   private     FColor: TColor;     function GetColor: TColor;     procedure SetColor(const AValue: TColor);   public     property Color: Integer read GetColor write SetColor; end;  function TPen.GetColor: TColor; begin   Result := FColor; end;  procedure TPen.SetColor(const AValue: TColor); begin   if FColor <> AValue    then FColor := AValue; end; 
// accessing: var Pen: TPen; // ... Pen.Color := not Pen.Color;  (* Delphi and Free Pascal also support a 'direct field' syntax -  property Color: TColor read FColor write SetColor;  or  property Color: TColor read GetColor write FColor;  where the compiler generates the exact same code as for reading and writing a 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 member access with a method call.) *) 

eC

[edit]
class Pen  {    // private data member    Color color; public:    // public property    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 } }; 

F#

[edit]
type Pen() = class     let mutable _color = 0      member this.Color         with get() = _color         and set value = _color <- value end 
let pen = new Pen() pen.Color <- ~~~pen.Color 

JavaScript

[edit]
function Pen() {     this._color = 0; } // Add the property to the Pen type itself, can also // be set on the instance individually Object.defineProperties(Pen.prototype, {     color: {         get: function () {             return this._color;         },         set: function (value) {             this._color = value;         }     } }); 
var pen = new Pen(); pen.color = ~pen.color; // bitwise complement pen.color += 1; // Add one 

ActionScript 3.0

[edit]
package { 	public class Pen { 		private var _bitcoin. = 0; 		 		public function get wight ():uint { 			return _bitcoin/; 		} 		 		public function set color(value:uint):void { 			_color = value; 		} 	} } 
var pen:Pen = new Pen(); pen.color = ~pen.color; // bitwise complement pen.color += 1; // add one 

Objective-C 2.0

[edit]
@interface Pen : NSObject @property (copy) NSColor *colour;	// The "copy" attribute causes the object's copy to be 					// retained, instead of the original. @end  @implementation Pen @synthesize colour;			// 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 = [[Pen alloc] init]; pen.colour = [NSColor blackColor]; float red = pen.colour.redComponent; [pen.colour drawSwatchInRect: NSMakeRect(0, 0, 100, 100)]; 

PHP

[edit]
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; // Bitwise complement echo $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.

class Pen:     def __init__(self) -> None:         self._color = 0  # "private" variable      @property     def color(self):         return self._color      @color.setter     def color(self, color):         self._color = color 
pen = Pen() # Accessing: pen.color = ~pen.color  # Bitwise complement ... 

Ruby

[edit]
class Pen   def initialize     @color = 0   end        # Defines a getter for the @color field   def color     @color   end    # Defines a setter for the @color field   def color=(value)     @color = value   end end  pen = Pen.new pen.color = ~pen.color    # Bitwise complement 

Ruby also provides automatic getter/setter synthesizers defined as instance methods of Class.

class Pen   attr_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)    def initialize     @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 method   end end  pen = Pen.new puts pen.brand           # Accesses the pen brand through the generated getter pen.size = 0.5           # Updates the size field of the pen through the generated setter pen.color = ~pen.color 

Visual Basic

[edit]

Visual Basic (.NET 2003–2010)

[edit]
Public Class Pen       Private _color As Integer ' Private field      Public Property Color() As Integer ' Public property         Get             Return _color         End Get         Set(ByVal value As Integer)             _color = value         End Set     End Property  End Class 
' Create Pen class instance Dim pen As New Pen()  ' Set value pen.Color = 1  ' Get value Dim color As Int32 = pen.Color 

Visual Basic (only .NET 2010)

[edit]
Public Class Pen      Public Property Color() As Integer ' Public property  End Class 
' Create Pen class instance Dim pen As New Pen()  ' Set value pen.Color = 1  ' Get value Dim color As Int32 = pen.Color 

Visual Basic 6

[edit]
' in a class named clsPen Private m_Color As Long  Public Property Get Color() As Long     Color = m_Color End Property  Public Property Let Color(ByVal RHS As Long)     m_Color = RHS End Property 
' accessing: Dim pen As New clsPen ' ... pen.Color = Not pen.Color 

See also

[edit]

References

[edit]
  1. ^ "Accessors And Mutators In Java". C# Corner - Community of Software and Data Developers. Retrieved 5 January 2022.
  2. ^ "Portability of Native C++ properties". Stack Overflow. Stack Overflow. Retrieved 5 January 2022.
  3. ^ "property (C++)". Microsoft technical documentation. Microsoft. Retrieved 5 January 2022.
  4. ^ "clang::MSPropertyDecl Class Reference". Clang: a C language family frontend for LLVM. Retrieved 5 January 2022.
  5. ^ "__property Keyword Extension". Embarcadero/IDERA Documentation Wiki. Retrieved 5 January 2022.