Article de reference

Propriété (programmation)

Une propriété , dans certains langages de programmation orientés objet , est un type particulier de membre de classe , intermédiaire en termes de fonctionnalité entre un champ (...

Une propriété , dans certains langages de programmation orientés objet , est un type particulier de membre de classe , intermédiaire en termes de fonctionnalité entre un champ (ou un membre de données) et une méthode . La syntaxe de lecture et d'écriture des propriétés est la même que pour les champs, mais les lectures et écritures de propriétés sont (généralement) traduites en appels de méthode « getter » et « setter ». La syntaxe de type champ est plus facile à lire et à écrire que de nombreux appels de méthode, pourtant l'interposition d'appels de méthode « sous le capot » permet la validation des données , la mise à jour active (par exemple, des éléments d'interface graphique ) ou l'implémentation de ce que l'on peut appeler des « champs en lecture seule ».

Assistance en langues

Les langages de programmation qui prennent en charge les propriétés incluent ActionScript 3 , C# , D , Delphi / Free Pascal , eC, F# , Kotlin , JavaScript , Objective-C 2.0 , Python , Scala , Swift , Lua et Visual Basic .

Certains langages orientés objet, tels que Java et C++ , ne prennent pas en charge les propriétés, ce qui oblige le programmeur à définir une paire de méthodes d'accès et de mutation

Oberon-2 fournit un mécanisme alternatif utilisant des indicateurs de visibilité des variables d'objet.

D'autres langages conçus pour la machine virtuelle Java , tels que Groovy , prennent en charge nativement les propriétés.

Bien que C++ ne possède pas de propriétés de première classe, elles peuvent être émulées avec la surcharge d'opérateur .

Notez également que certains compilateurs C++ prennent en charge les propriétés de première classe en tant qu'extensions de langage.

Dans de nombreux langages orientés objet, les propriétés sont implémentées sous la forme d'une paire de méthodes d'accès/mutation, mais l'accès s'effectue à l'aide de la même syntaxe que pour les champs publics. L'omission d'une méthode de la paire génère une propriété en lecture seule ou une propriété en écriture seule peu courante .

Dans certains langages ne prenant pas en charge les propriétés de manière intégrée, une construction similaire peut être implémentée sous la forme d'une méthode unique qui renvoie ou modifie les données sous-jacentes, selon le contexte de son appel. De telles techniques sont utilisées par exemple dans Perl .

Certains langages ( Ruby , Smalltalk ) parviennent à une syntaxe de type propriété en utilisant des méthodes normales, parfois avec une quantité limitée de sucre syntaxique .

Variantes de syntaxe

Certains langages suivent des conventions syntaxiques bien établies pour spécifier et utiliser formellement des propriétés et des méthodes.

Parmi ces conventions :

  • Notation par points
  • Notation entre parenthèses

Notation par points

L'exemple suivant illustre la notation par points en JavaScript.

document . createElement ( 'pré' );

Notation entre parenthèses

L'exemple suivant illustre la notation entre crochets en JavaScript.

document [ 'createElement' ]( 'pré' );

Exemple de syntaxe

C#

classe Pen { private int color ; // champ privé // propriété publique public int Color { get { return this . color ; } set { if ( value > 0 ) { this . color = value ; } } } }
// accès à : 
Pen pen = new Pen (); int color_tmp = 0 ; // ... pen . Color = 17 ; color_tmp = pen . Color ; // ... pen . Color = ~ pen . Color ; // complément binaire ...
// un autre exemple idiot : 
pen . Color += 1 ; // beaucoup plus clair que "pen.set_Color(pen.get_Color() + 1)"!

Les versions récentes de C# autorisent également les « propriétés implémentées automatiquement » où le champ de sauvegarde de la propriété est généré par le compilateur pendant la compilation. Cela signifie que la propriété doit avoir un setter. Cependant, il peut être privé.

classe Forme { public int Hauteur { obtenir ; définir ; } public int Largeur { obtenir ; privé définir ; } }

C++

Le C++ ne possède pas de propriétés de première classe, mais il existe plusieurs façons d'émuler des propriétés à un degré limité. En voici deux :

Utilisation du C++ standard

#include <iostream>
template < typename T > class property { T value ; public : T & operator = ( const T & i ) { return value = i ; } // Cette fonction membre de classe template a pour but de rendre le typage plus strict. L'affectation à ceci n'est possible qu'avec des types exactement identiques. // La raison pour laquelle cela provoquera une erreur est la variable temporaire créée lors de la conversion de type implicite dans l'initialisation de référence. template < typename T2 > T2 & operator = ( const T2 & i ) { T2 & guard = value ; throw guard ; // Jamais atteint. }
// Conversion implicite en T. 
opérateur T const & () const { return value ; } };
struct Foo { // Propriétés utilisant des classes sans nom. class { int value ; public : int & operator = ( const int & i ) { return value = i ; } operator int () const { return value ; } } alpha ;
classe { valeur flottante ; public : float & opérateur = ( const float & f ) { valeur de retour = f ; } opérateur float () const { valeur de retour ; } } bravo ; };
struct Bar { // Utilisation du modèle property<>. 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 ; // Cette ligne génèrera une erreur de compilation // en raison de la fonction membre du modèle de garde. :: std :: cout << foo . alpha << ", " << foo . bravo << ", " << bar . alpha << ", " << bar . bravo << :: std :: endl ; return 0 ; }

Voir également Stack Overflow pour un exemple plus détaillé.

Spécifique à C++, Microsoft, GCC, LLVM/clang et C++Builder

Un exemple tiré de la page de documentation MSDN.

// declspec_property.cpp 
struct S { int i ; void putprop ( int j ) { i = j ; }
int getprop () { renvoie i ; }
__declspec ( propriété ( get = getprop , put = putprop )) int the_prop ; };
int main () { S s ; s . the_prop = 5 ; return s . the_prop ; }

D

classe Pen { private int m_color ; // champ privé // public obtenir la propriété public int color () { return m_color ; } // public définir la propriété public void color ( int value ) { m_color = value ; } }
auto pen = new Pen ; pen . color = ~ pen . color ; // complément binaire
// la propriété set peut également être utilisée dans des expressions, tout comme une affectation classique 
int theColor = ( pen . color = 0xFF0000 );

Dans la version D 2, chaque accesseur ou mutateur de propriété doit être marqué avec @property :

classe Pen { private int m_color ; // champ privé // public obtenir la propriété @property public int color () { return m_color ; } // public définir la propriété @property public void color ( int value ) { m_color = value ; } }

Delphi/Free Pascal

type TPen = classe privée FColor : TColor ; fonction GetColor : TColor ; procédure SetColor ( const AValue : TColor ) ; propriété publique Color : Integer lecture GetColor écriture SetColor ; fin ;
fonction TPeen . GetColor : TColor ; début Résultat := FColor ; fin ;
procédure TPen . SetColor ( const AValue : TColor ) ; début si FColor <> AValue alors FColor := AValue ; fin ;
// accès à : 
var Pen : TPen ; // ... Pen . Color := pas Pen . Color ;
(* 
Delphi et Free Pascal prennent également en charge une syntaxe de « champ direct » -
propriété Couleur : TColor lecture FColor écriture SetColor ;
ou
propriété Couleur : TColor lecture GetColor écriture FColor ;
où le compilateur génère exactement le même code que pour la lecture et l'écriture 
d'un champ. Cela offre l'efficacité d'un champ, avec la sécurité d'une propriété. 
(Vous ne pouvez pas obtenir de pointeur vers la propriété, et vous pouvez toujours remplacer l' 
accès au membre par un appel de méthode.) 
*)

CE

classe Pen { // membre de données privé Color color ; public : // propriété publique property Color color { get { return color ; } set { color = value ; } } } Stylo blackPen { color = black }; Stylo whitePen { color = white }; Stylo pen3 { color = { 30 , 80 , 120 } }; Stylo pen4 { color = ColorHSV { 90 , 20 , 40 } };

Fa#

type Pen () = classe let mutable _ couleur = 0
membre ceci . Couleur avec get () = _ color et set value = _ color <- value end
laissez pen = new Pen () pen . Couleur <- ~~~ pen . Couleur

JavaScript

function Pen () { this . _color = 0 ; } // Ajouter la propriété au type Pen lui-même, peut également // être défini sur l'instance individuellement Object . defineProperties ( Pen . prototype , { color : { get : function () { return this . _color ; }, set : function ( value ) { this . _color = value ; } } });
var pen = new Pen ( ); pen.color = ~ pen.color ; // complément binaire pen.color + = 1 ; // Ajouter un

ActionScript 3.0

paquet { classe publique Pen { var privée _bitcoin . = 0 ; fonction publique get wight () : uint { return _bitcoin /; } fonction publique set color ( valeur : uint ): void { _color = valeur ; } } }
var pen : Pen = new Pen ( ); pen.color = ~ pen.color ; // complément binaire pen.color + = 1 ; // ajouter un

Objective-C 2.0

@interface 
Pen : NSObject 
@property ( copy ) NSColor * colour ; // L'attribut "copy" provoque la conservation de la copie de l'objet, au lieu de l'original. @end
@implementation 
Pen 
@synthesize colour ; // Directive du compilateur pour synthétiser les méthodes d'accès. // Elle peut être laissée de côté dans Xcode 4.5 et versions ultérieures. @end

L'exemple ci-dessus pourrait être utilisé dans une méthode arbitraire comme celle-ci :

Stylo * stylo = [[ Pen alloc ] init ]; stylo . couleur = [ NSColor blackColor ]; float rouge = stylo . couleur . redComponent ; [ stylo . couleur drawSwatchInRect : NSMakeRect ( 0 , 0 , 100 , 100 )];

PHP

classe 
Pen 
{ 
privé 
int 
$color 
= 
1 ;
fonction 
__set ( $propriété , 
$valeur ) 
{ 
si 
( propriété_existe ( $this , 
$propriété )) 
{ 
$this -> $propriété 
= 
$valeur ; 
} 
}
fonction 
__get ( $property ) 
{ 
si 
( property_exists ( $this , 
$property )) 
{ 
retourner 
$this -> $property ; 
} 
retourner 
null ; 
} 
}
$p 
= 
new 
Pen (); 
$p -> couleur 
= 
~ $p -> couleur ; 
// Complément binaire 
echo 
$p -> couleur ;

Python

Les propriétés ne fonctionnent correctement que pour les classes de nouveau style (classes qui ont objectcomme superclasse ) et ne sont disponibles que dans Python 2.2 et versions ultérieures (voir la section correspondante du tutoriel Unification des types et des classes dans Python 2.2). Python 2.6 a ajouté une nouvelle syntaxe impliquant des décorateurs pour définir les propriétés.

classe 
Pen : 
def 
__init__ ( self ) 
-> 
None : 
self . _color 
= 
0 
# variable "privée"
@property 
def 
couleur ( self ): 
renvoie 
self . _color
@color . setter 
def 
couleur ( self , 
couleur ): 
self . _color 
= 
couleur
pen 
= 
Pen () 
# Accès à : 
pen . color 
= 
~ pen . color 
# Complément binaire ...

Rubis

classe Pen def initialize @color = 0 end # Définit un getter pour le champ @color def color @color end
# Définit un setter pour le champ @color 
def color= ( value ) @color = value end end
stylo = Stylo . nouveau stylo . couleur = ~ stylo . couleur # Complément binaire

Ruby fournit également des synthétiseurs getter/setter automatiques définis comme des méthodes d'instance de Class.

classe Pen attr_reader :brand # Génère un getter pour @brand (lecture seule) attr_writer :size # Génère un setter pour @size (écriture seule) attr_accessor :color # Génère un getter et un setter pour @color (lecture/écriture)
def initialize @color = 0 # Dans l'objet, nous pouvons accéder directement à la variable d'instance @brand = "Penbrand" @size = 0 . 7 # Mais nous pourrions également utiliser la méthode setter définie par la méthode d'instance de classe attr_accessor end end
pen = Pen . new puts pen . brand # Accède à la marque du stylo via le getter généré pen . size = 0 . 5 # Met à jour le champ de taille du stylo via le setter généré pen . color = ~ pen . color

Visual Basic

Visual Basic (.NET 2003-2010)

Classe publique Pen Private _color As Integer ' Champ privé
Propriété publique Color () As Integer ' Propriété publique Get Return _color End Get Set ( ByVal value As Integer ) _color = value End Set End Propriété
Fin de cours
' Créer une instance de classe Pen 
Dim pen As New Pen ()
' Définir la valeur 
du stylo . Couleur = 1
' Obtenir la valeur 
Dim color comme Int32 = pen . Color

Visual Basic (uniquement .NET 2010)

Stylo de classe publique
Propriété publique Couleur () As Integer ' Propriété publique
Fin de cours
' Créer une instance de classe Pen 
Dim pen As New Pen ()
' Définir la valeur 
du stylo . Couleur = 1
' Obtenir la valeur 
Dim color comme Int32 = pen . Color

Visual Basic 6

' dans une classe nommée clsPen 
Private m_Color As Long
Propriété publique Obtenir la couleur () comme Long Color = m_Color Fin de la propriété
Propriété publique Let Color ( ByVal RHS As Long ) m_Color = RHS Fin de la propriété
' accès à : 
Dim pen As New clsPen ' ... pen . Couleur = Pas pen . Couleur

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index