オブジェクト指向プログラミング言語におけるプロパティは、フィールド(またはデータメンバー)とメソッドの中間的な機能を持つ、特殊なクラスメンバーです。プロパティの読み書き構文はフィールドと同様ですが、プロパティの読み書きは(通常)「ゲッター」メソッドと「セッター」メソッドの呼び出しに変換されます。フィールドのような構文は、多くのメソッド呼び出しよりも読み書きが容易ですが、メソッド呼び出しが内部的に介在することで、データの検証、アクティブな更新(例えば、グラフィカルユーザーインターフェース(GUI)要素の更新)、あるいは「読み取り専用フィールド」と呼ばれるものの実装が可能になります。
プロパティをサポートするプログラミング言語には、C#、D、ECMAScript(ActionScript 3、JavaScript)、eC、F#、Kotlin、Object Pascal(Delphi、Free Pascal)、Objective-C 2.0、Python、Scala、Swift、Lua、Visual Basicなどがあります。
JavaやC++などの一部のオブジェクト指向言語はプロパティをサポートしていないため、プログラマーは代わりにアクセサメソッドとミューテータメソッドのペアを定義する必要がある。[ 1 ]
Oberon-2は、オブジェクト変数の可視性フラグを使用した代替メカニズムを提供します。
Java仮想マシン向けに設計された他の言語、例えばGroovyなどは、プロパティをネイティブにサポートしています。
C++には第一級プロパティはありませんが、演算子オーバーロードでエミュレートできます。[ 2 ]
一部のC++コンパイラは、言語拡張機能として第一級プロパティをサポートしています。
__declspec(property)__property。[ 5 ]多くのオブジェクト指向言語では、プロパティはアクセサメソッドとミューテータメソッドのペアとして実装されますが、パブリックフィールドと同じ構文でアクセスされます。このペアからメソッドを1つ省略すると、読み取り専用プロパティ、またはまれに書き込み専用プロパティになります。
プロパティを標準でサポートしていない言語では、呼び出しのコンテキストに応じて基となるデータを返すか変更するかのどちらかを選択する単一のメソッドとして同様の構造を実装できます。このような手法は、例えばPerlで使用されています。
一部の言語(Ruby、Smalltalkなど)は、通常のメソッドを使用してプロパティのような構文を実現しており、場合によっては限られた量の構文糖衣を使用しています。
一部のプログラミング言語は、プロパティやメソッドを正式に指定および利用するための、確立された構文規則に従っている。
これらの慣習の中には、次のようなものがある。
以下の例は、JavaScriptにおけるドット表記法を示しています。
document.createElement ( "pre " ) ;以下の例は、JavaScriptにおける括弧表記法を示しています。
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#バージョンでは、「自動実装プロパティ」も使用可能になりました。これは、プロパティのバッキングフィールドがコンパイル時にコンパイラによって生成されるというものです。つまり、プロパティにはセッターが必要ですが、プライベートにすることができます。
class Shape { public int Height { get ; set ; } public int Width { get ; private set ; } }C++には第一級プロパティはありませんが、プロパティをある程度エミュレートする方法がいくつかあります。そのうちの2つを以下に示します。
import 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 ; }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 ; //ビットごとの補数// set プロパティは、通常の代入と同様に式でも使用できます。int theColor = ( pen . color = 0xFF0000 );D バージョン 2 では、各プロパティ アクセサーまたはミューテーターには @property を付ける必要があります。
class Pen { private int myColor ; // プライベートフィールド// パブリックなgetプロパティ@property public int color () { return myColor ; } // パブリックなsetプロパティ@property public void color ( int value ) { myColor = value ; } }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 } };type Pen () = class let mutable _ color = 0メンバーthis . Color をget () = _ colorで取得し、値を_ color <- valueに設定します。let pen = new Pen ( ) pen.Color < - ~~~ pen.Colorfunction 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 ; // 1を加える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 ; // 1を加える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 ;手順TPen 。SetColor ( const AValue : TColor ) ; begin if FColor <> AValue then FColor := AValue ;終わり;// アクセス: var Pen : TPen ; // ... Pen . Color := not Pen . Color ;(* Delphi と Free Pascal も「直接フィールド」構文をサポートしています -プロパティ Color: TColor 読み取り、FColor 書き込み、SetColor 書き込み;またはプロパティ Color: TColor 読み取り GetColor 書き込み FColor;コンパイラは、フィールドの読み書きとまったく同じコードを生成します。これにより、フィールドの効率性とプロパティの安全性が両立します。(ポインタはプロパティにアクセスできず、メンバへのアクセスは常にメソッド呼び出しに置き換えることができます。)@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 )];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としてを持つクラス)でのみ正しく機能し、Python 2.2 以降でのみ利用可能です(チュートリアル「Python 2.2 での型とクラスの統一」の該当セクションを参照)。Python 2.6 では、プロパティを定義するためのデコレータを含む新しい構文が追加されました。
クラス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 = colorpen : Pen = Pen () # アクセス: pen . color = ~ pen . color # ビットごとの補数 ...class Pen def initialize @color = 0 end # @color フィールドのゲッターを定義しますdef color @color end# @color フィールドのセッターを定義しますdef color= ( value ) @color = value end endpen = Pen.new pen.color = ~ pen.color #ビットごとの補数Rubyには、Classのインスタンスメソッドとして定義された自動ゲッター/セッターシンセサイザーも用意されています。
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 #生成されたゲッターを介してペンのブランドにアクセスしますpen.size = 0.5 #生成されたセッターを介してペンのサイズフィールドを更新しますpen.color = ~ pen.colorPublic Class Pen Private _color As Integer ' プライベートフィールドPublic Property Color () As Integer ' Public property Get Return _color End Get Set ( ByVal value As Integer ) _color = value End Set End Propertyエンドクラス' Pen クラスのインスタンスを作成しますDim pen As New Pen ()' 値ペンを設定します。色= 1' 値を取得するDim color As Int32 = pen.Color公共の階級の刑務所パブリックプロパティの色()整数型'パブリックプロパティエンドクラス' Pen クラスのインスタンスを作成しますDim pen As New Pen ()' 値ペンを設定します。色= 1' 値を取得するDim color As Int32 = pen.Color' clsPen という名前のクラス内でPrivate m_Color As LongパブリックプロパティGet Color () As Long Color = m_Color End PropertyPublic Property Let Color ( ByVal RHS As Long ) m_Color = RHS End Property' アクセス: Dim pen As New clsPen ' ... pen . Color = Not pen . Color