stringtranslate.com

Propiedad (programación)

Una propiedad , en algunos lenguajes de programación orientados a objetos , es un tipo especial de miembro de clase , de funcionalidad intermedia entre un campo (o miembro de datos) y un método . La sintaxis para leer y escribir propiedades es como la de los campos, pero las lecturas y escrituras de propiedades se traducen (generalmente) a llamadas a métodos ' getter ' y ' setter '. La sintaxis similar a un campo es más fácil de leer y escribir que muchas llamadas a métodos, [ cita necesaria ] sin embargo, la interposición de llamadas a métodos "bajo el capó" permite la validación de datos , la actualización activa (por ejemplo, de elementos de la GUI ) o la implementación de lo que pueden denominarse "campos de sólo lectura".

Soporte en idiomas

Los lenguajes de programación que admiten propiedades incluyen ActionScript 3 , C# , D , Delphi / Free Pascal , eC , F# , Kotlin , JavaScript , Objective-C 2.0 , Python , Scala , Swift , Lua y Visual Basic .

Algunos lenguajes orientados a objetos, como Java y C++ , no admiten propiedades, lo que requiere que el programador defina un par de métodos de acceso y mutador . [1] [ cita necesaria ]

Oberon-2 proporciona un mecanismo alternativo que utiliza indicadores de visibilidad de variables de objetos. [ cita necesaria ]

Otros lenguajes diseñados para la máquina virtual Java , como Groovy , admiten propiedades de forma nativa.

Si bien C++ no tiene propiedades de primera clase, se pueden emular con la sobrecarga de operadores . [2]

Tenga en cuenta también que algunos compiladores de C++ admiten propiedades de primera clase como extensiones del lenguaje. [ cita necesaria ]

En muchos lenguajes orientados a objetos, las propiedades se implementan como un par de métodos de acceso/mutador, pero se accede a ellas utilizando la misma sintaxis que para los campos públicos. Omitir un método del par produce una propiedad de solo lectura o de solo escritura poco común .

En algunos lenguajes sin soporte integrado para propiedades, se puede implementar una construcción similar como un método único que devuelve o cambia los datos subyacentes, según el contexto de su invocación. Estas técnicas se utilizan, por ejemplo, en Perl . [ cita necesaria ]

Algunos lenguajes ( Ruby , Smalltalk ) logran una sintaxis similar a una propiedad utilizando métodos normales, a veces con una cantidad limitada de azúcar sintáctico .

Variantes de sintaxis

Algunos lenguajes siguen convenciones de sintaxis bien establecidas para especificar y utilizar formalmente propiedades y métodos.

Entre estas convenciones:

Notación de puntos

El siguiente ejemplo demuestra la notación de puntos en JavaScript.

documento . crearElemento ( 'pre' );

Notación entre corchetes

El siguiente ejemplo demuestra la notación entre corchetes en JavaScript.

documento [ 'createElement' ]( 'pre' );

Sintaxis de ejemplo

C#

clase Pluma { privado int color ; // campo privado // propiedad pública public int Color { get { return this . color ; } establecer { si ( valor > 0 ) { esto . color = valor ; } } } }                                 
// accediendo a: Pluma pluma = nueva Pluma (); int color_tmp = 0 ; // ... bolígrafo . Color = 17 ; color_tmp = bolígrafo . Color ; // ... bolígrafo . Color = ~ bolígrafo . Color ; // complemento bit a bit...              // otro ejemplo tonto: bolígrafo . Color += 1 ; // ¡mucho más claro que "pen.set_Color(pen.get_Color() + 1)"!   

Las versiones recientes de C# también permiten "propiedades implementadas automáticamente" donde el compilador genera el campo de respaldo para la propiedad durante la compilación. Esto significa que la propiedad debe tener un definidor. Sin embargo, puede ser privado.

clase Forma { public int Altura { get ; colocar ; } public int Ancho { get ; conjunto privado ; } }                 

C++

C++ no tiene propiedades de primera clase, pero existen varias formas de emular propiedades hasta cierto punto. Dos de los cuales siguen:

Usando C++ estándar

#incluir <iostream> plantilla < nombre de tipo T > propiedad de clase { valor T ; público : T & operador = ( const T & i ) { valor de retorno = i ; } // Esta plantilla de función de miembro de clase de plantilla sirve para hacer // la escritura más estricta. La asignación a esto sólo es posible con tipos exactamente idénticos. // La razón por la que causará un error es que la variable temporal se crea durante la conversión de tipo implícita en la inicialización de la referencia. plantilla < nombre de tipo T2 > T2 y operador = ( const T2 y i ) { T2 y guardia = valor ; tirar guardia ; // Nunca alcanzado. }                                            // Conversión implícita de nuevo a T. operador T const & () const { valor de retorno ; } };          struct Foo { // Propiedades que utilizan clases sin nombre. clase { int valor ; público : int & operador = ( const int & i ) { valor de retorno = i ; } operador int () const { valor de retorno ; } } alfa ;                                clase { valor flotante ; público : flotador y operador = ( const flotador y f ) { valor de retorno = f ; } operador float () const { valor de retorno ; } } bravo ; };                           struct Bar { // Usando la propiedad<>-template. propiedad < bool > alfa ; propiedad < unsigned int > bravo ; };          int principal () { Foo foo ; foo . alfa = 5 ; foo . bravo = 5.132f ;            barra- barra ; bar . alfa = verdadero ; bar . bravo = verdadero ; // Esta línea producirá un error en tiempo de compilación // debido a la función miembro de la plantilla de protección. :: std :: cout << foo . alfa << ", " << foo . bravo << ", " << barra . alfa << ", " << barra . bravo << :: std :: endl ; devolver 0 ; }                            

Consulte también Stack Overflow para ver un ejemplo más detallado.

C++, Microsoft, GCC, LLVM/clang y específico de C++Builder

Un ejemplo tomado de la página de documentación de MSDN.

// declspec_property.cpp estructura S { int i ; void putprop ( int j ) { i = j ; }             int getprop () { retorno i ; }      __declspec ( propiedad ( get = getprop , put = putprop )) int the_prop ; };       int principal () { S s ; s . la_prop = 5 ; devoluciones .la_propiedad ; }        

D

clase Pluma { privado int m_color ; // campo privado // propiedad pública obtener public int color () { return m_color ; } // propiedad pública establecida color vacío público ( valor int ) { m_color = valor ; } }                           
bolígrafo automático = bolígrafo nuevo ; bolígrafo . color = ~ bolígrafo . color ; // complemento bit a bit       // la propiedad set también se puede utilizar en expresiones, al igual que la asignación normal int theColor = ( pen . color = 0xFF0000 );     

En D versión 2, cada descriptor de acceso o mutador de propiedad debe marcarse con @property:

clase Pluma { privado int m_color ; // campo privado // propiedad pública obtener @property public int color () { return m_color ; } // propiedad pública establecida @property color vacío público ( valor int ) { m_color = valor ; } }                             

Delfos/Pascal libre

tipo TPen = clase privada FColor : TColor ; función ObtenerColor : TColor ; procedimiento SetColor ( const AValue : TColor ) ; propiedad pública Color : Entero leer GetColor escribir SetColor ; fin ;                     Función TPen . ObtenerColor : TColor ; comenzar resultado : = FColor ; fin ;     procedimiento TPen . EstablecerColor ( const AValue : TColor ) ; comience si FColor <> AValue entonces FColor := AValue ; fin ;           
// accediendo a: var Pluma : TPen ; // ... Bolígrafo . Color : = no bolígrafo . Color ;     (* Delphi y Free Pascal también admiten una sintaxis de 'campo directo' -propiedad Color: TColor leer FColor escribir SetColor;opropiedad Color: TColor leer GetColor escribir FColor;donde el compilador genera exactamente el mismo código que para leer y escribir un campo. Esto ofrece la eficiencia de un campo, con la seguridad de una propiedad. (No puede obtener un puntero a la propiedad y siempre puede reemplazar el acceso del miembro con una llamada al método). *)

CE

class Pluma { // miembro de datos privados Color color ; public : //propiedad pública propiedad Color color { get { return color ; } establecer { color = valor ; } } } Bolígrafo negroPluma { color = negro }; Bolígrafo blancoPluma { color = blanco }; Bolígrafo bolígrafo3 { color = { 30 , 80 , 120 } }; Pluma pluma4 { color = ColorHSV { 90 , 20 , 40 } };                                                         

F#

tipo Pluma () = clase let mutable _ color = 0         miembro esto . Color con get ( ) = _color y set valor = _color < - valor final            
let pen = new Pen () pen . Color <- ~~~ bolígrafo . Color      

javascript

función Pluma () { esto . _color = 0 ; } // Agregue la propiedad al tipo de Pluma en sí, // también se puede establecer en la instancia individualmente Objeto . defineProperties ( Pluma . prototipo , { color : { obtener : función () { devolver esto . _color ; }, establecer : función ( valor ) { esto . _color = valor ; } } });                        
var pluma = nueva Pluma (); bolígrafo . color = ~ bolígrafo . color ; // pluma de complemento bit a bit . color += 1 ; // Agrega uno          

ActionScript 3.0

paquete { pluma de clase pública { var privada _bitcoin . = 0 ; funcion publica get wight (): uint { return _bitcoin /; } función pública establecer color ( valor : uint ): void { _color = valor ; } } }                    
var pluma : Pluma = nueva Pluma (); bolígrafo . color = ~ bolígrafo . color ; // pluma de complemento bit a bit . color += 1 ; // Agrega uno          

Objetivo-C 2.0

@interface  Pluma  : NSObject @property ( copia ) NSColor * color ; // El atributo "copia" hace que se retenga // la copia del objeto , en lugar del original. @fin   @implementation  Pluma @synthesize color ; // Directiva del compilador para sintetizar métodos de acceso. // Puede quedar atrás en Xcode 4.5 y posteriores. @fin 

El ejemplo anterior podría usarse en un método arbitrario como este:

Pluma * pluma = [[ Pen alloc ] init ]; bolígrafo . color = [ NSColor colornegro ]; flotador rojo = bolígrafo . color . componente rojo ; [ bolígrafo . color drawSwatchInRect : NSMakeRect ( 0 , 0 , 100 , 100 )];                

PHP

clase  Pluma {  privado  int  $color  =  1 ; función  __set ( $propiedad ,  $valor )  {  if  ( propiedad_existe ( $esto ,  $propiedad ))  {  $esto -> $propiedad  =  $valor ;  }  } función  __get ( $propiedad )  {  if  ( propiedad_existe ( $esto ,  $propiedad ))  {  return  $esto -> $propiedad ;  }  devolver  nulo ;  } }
$p  =  nuevo  bolígrafo (); $p -> color  =  ~ $p -> color ;  // Complemento bit a bit echo  $p -> color ;

Pitón

Las propiedades solo funcionan correctamente para clases de nuevo estilo (clases que tienen objectcomo superclase ) y solo están disponibles en Python 2.2 y posteriores (consulte la sección correspondiente del tutorial Unificación de tipos y clases en Python 2.2). Python 2.6 agregó una nueva sintaxis que involucra decoradores para definir propiedades.

clase  Pluma :  def  __init__ ( self )  ->  Ninguno :  self . _color  =  0  # variable "privada" @property  def  color ( self ):  devuelve  self . _color @color . setter  def  color ( self ,  color ):  self . _color  =  color
pluma  =  Pluma () # Accediendo a: pluma . color  =  ~ bolígrafo . color  # Complemento bit a bit...

Rubí

class Pen def inicializar @color = 0 end # Define un captador para el campo @color def color @color end              # Define un definidor para el campo @color def color= ( valor ) @color = valor fin fin      bolígrafo = bolígrafo . bolígrafo nuevo . color = ~ bolígrafo . color # Complemento bit a bit     

Ruby también proporciona sintetizadores getter/setter automáticos definidos como métodos de instancia de Class.

class Pen attr_reader :brand # Genera un captador para @brand (solo lectura) attr_writer :size # Genera un definidor para @size (solo escritura) attr_accessor :color # Genera un captador y un definidor para @color (lectura/escritura)           def inicializar @color = 0 # Dentro del objeto, podemos acceder a la variable de instancia directamente @brand = "Penbrand" @size = 0 . 7 # Pero también podríamos usar el método setter definido por el método de instancia de clase attr_accessor end end             bolígrafo = bolígrafo . nuevo pone bolígrafo . brand # Accede a la marca del lápiz a través del lápiz getter generado . tamaño = 0 . 5 # Actualiza el campo de tamaño del lápiz a través del lápiz configurador generado . color = ~ bolígrafo . color         

Visual Básico

Visual Básico (.NET 2003–2010)

Public Class Pen Private _color As Integer ' Campo privado         Color de propiedad pública () como entero ' Propiedad pública Obtener Retorno _color Fin Obtener conjunto ( valor ByVal como entero ) _color = valor Fin Establecer propiedad final                     Fin de clase 
'Crear instancia de clase Pluma Atenuar pluma como pluma nueva ()    ' Establecer valor pluma . Color = 1  'Obtiene valor Color atenuado Como Int32 = pluma . Color     

Visual Basic (solo .NET 2010)

Pluma de clase pública   Color de propiedad pública () como número entero ' Propiedad pública     Fin de clase 
'Crear instancia de clase Pluma Atenuar pluma como pluma nueva ()    ' Establecer valor pluma . Color = 1  'Obtiene valor Color atenuado Como Int32 = pluma . Color     

Visual Basic 6

' en una clase llamada clsPen Private m_Color As Long   Propiedad pública Obtener color () siempre que Color = m_Color Propiedad final         Propiedad pública Let Color ( ByVal RHS As Long ) m_Color = Propiedad final RHS          
'accediendo: Dim pen As New clsPen '... pen . Color = No bolígrafo . Color       

Ver también

Referencias

  1. ^ "Accesorios y mutadores en Java". C# Corner: comunidad de desarrolladores de software y datos . Consultado el 5 de enero de 2022 .
  2. ^ "Portabilidad de propiedades nativas de C++". Desbordamiento de pila . Desbordamiento de pila . Consultado el 5 de enero de 2022 .
  3. ^ "propiedad (C++)". Documentación técnica de Microsoft . Microsoft . Consultado el 5 de enero de 2022 .
  4. ^ "clang::Referencia de clase MSPropertyDecl". Clang: una interfaz de la familia de lenguaje C para LLVM . Consultado el 5 de enero de 2022 .
  5. ^ "__property Extensión de palabras clave". Embarcadero/IDERA Documentación Wiki . Consultado el 5 de enero de 2022 .