stringtranslate.com

Propiedad (programación)

Una propiedad , en algunos lenguajes de programación orientados a objetos , es un tipo especial de miembro de clase , intermedio en funcionalidad entre un campo (o miembro de datos) y un método . La sintaxis para leer y escribir propiedades es como para los campos, pero las lecturas y escrituras de propiedades se traducen (normalmente) en llamadas a métodos ' getter ' y ' setter '. La sintaxis similar a la de los campos es más fácil de leer y escribir que muchas llamadas a métodos, [ cita requerida ] sin embargo, la interposición de llamadas a métodos "de forma oculta" permite la validación de datos , la actualización activa (por ejemplo, de elementos de la GUI ) o la implementación de lo que se puede llamar "campos de solo 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 en su lugar un par de métodos de acceso y mutación . [1] [ cita requerida ]

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

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, éstas se pueden emular con sobrecarga de operadores . [2]

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

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

En algunos lenguajes que no tienen 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 requerida ]

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áctica .

Variantes de sintaxis

Algunos lenguajes siguen convenciones sintácticas 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 .createElement ( 'pre' ) ;

Notación entre corchetes

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

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

Ejemplo de sintaxis

DO#

clase Pen { int privado color ; // campo privado // propiedad pública int público Color { obtener { devolver este . color ; } establecer { si ( valor > 0 ) { este . color = valor ; } } } }                                 
// accediendo a: Pen pen = new Pen (); int color_tmp = 0 ; // ... pen . Color = 17 ; color_tmp = pen . Color ; // ... pen . Color = ~ pen . Color ; // complemento bit a bit ...              // otro ejemplo tonto: pen . 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" en las que el compilador genera el campo de respaldo de la propiedad durante la compilación. Esto significa que la propiedad debe tener un definidor. Sin embargo, puede ser privado.

clase Forma { int público Altura { obtener ; establecer ; } int público Ancho { obtener ; establecer ; } }                 

C++

C++ no tiene propiedades de primera clase, pero existen varias formas de emular propiedades en un grado limitado. Dos de ellas son las siguientes:

Usando C++ estándar

#include <flujo de datos> plantilla < typename T > propiedad de clase { T valor ; público : T & operador = ( const T & i ) { valor de retorno = i ; } // Esta función miembro de clase de plantilla tiene como finalidad hacer que la tipificación sea más estricta. La asignación a esta función solo es posible con tipos exactamente idénticos. // La razón por la que provocará un error es la variable temporal creada durante la conversión de tipo implícita en la inicialización de la referencia. plantilla < typename T2 > T2 & operador = ( const T2 & i ) { T2 & guard = valor ; throw guard ; // Nunca se alcanza. }                                            // 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 : flotante y operador = ( const flotante y f ) { valor de retorno = f ; } operador flotante () const { valor de retorno ; } } bravo ; };                           struct Bar { // Usando la propiedad<>-template. propiedad < bool > alpha ; propiedad < unsigned int > bravo ; };          int main ( ) { Foo foo ; foo.alpha = 5 ; foo.bravo = 5.132f ;            Bar bar ; bar . alpha = true ; bar . bravo = true ; // Esta línea producirá un error de tiempo de compilación // debido a la función miembro de plantilla de protección. :: std :: cout << foo . alpha << ", " << foo . bravo << ", " << bar . alpha << ", " << bar . bravo << :: std :: endl ; return 0 ; }                            

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

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

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 () { devolver i ; }      __declspec ( propiedad ( obtener = getprop , poner = putprop )) int the_prop ; };       int main () { S s ; s . la_propiedad = 5 ; devolver s . la_propiedad ; }        

D

clase Pen { private int m_color ; // campo privado // propiedad pública get public int color () { return m_color ; } // propiedad pública set public void color ( int value ) { m_color = value ; } }                           
auto pen = new Pen ; pen . color = ~ pen . color ; // complemento bit a bit       // la propiedad establecida también se puede usar en expresiones, al igual que la asignación regular int theColor = ( pen . color = 0xFF0000 );     

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

clase Pen { int privado m_color ; // campo privado // propiedad pública obtenida @propiedad pública int color () { devolver m_color ; } // propiedad pública establecida @propiedad pública void color ( int valor ) { m_color = valor ; } }                             

Delphi/Pascal libre

tipo TPen = clase privada FColor : TColor ; función GetColor : TColor ; procedimiento SetColor ( const AValue : TColor ) ; propiedad pública Color : Integer leer GetColor escribir SetColor ; fin ;                     función TPen . GetColor : TColor ; inicio Resultado := FColor ; fin ;     procedimiento TPen . SetColor ( const AValue : TColor ) ; comienzo si FColor <> AValue entonces FColor := AValue ; fin ;           
// accediendo: var Pen : TPen ; // ... Pen . Color := no Pen . 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 se puede obtener un puntero a la propiedad y siempre se puede reemplazar el acceso al miembro con una llamada a un método). *)

CE

clase Pluma { // miembro de datos privados Color color ; público : // propiedad pública propiedad Color color { obtener { devolver color ; } establecer { color = valor ; } } } Pluma PlumaNegra { color = negro }; Pluma PlumaBlanca { color = blanco }; Pluma Pluma3 { color = { 30 , 80 , 120 } }; Pluma Pluma4 { color = ColorHSV { 90 , 20 , 40 } };                                                         

F#

tipo Pen () = clase let mutable _ color = 0         Miembro de este . Color con get () = _ color y set value = _ color <- value end            
deje que lapiz = new Lapiz ( ) lapiz.Color < - ~~~ lapiz.Color      

JavaScript

function Pen () { this._color = 0 ; } // Agrega la propiedad al tipo Pen en sí, también se puede // establecer en la instancia individualmente Object.defineProperties ( Pen.prototype , { color : { get : function ( ) { return this._color ; } , set : function ( value ) { this._color = value ; } } } ) ;                        
var pen = new Pen (); pen . color = ~ pen . color ; // complemento bit a bit pen . color += 1 ; // Agregar uno          

ActionScript 3.0

paquete { clase pública Pen { var privada _bitcoin . = 0 ; función pública obtener peso (): uint { devolver _bitcoin /; } función pública establecer color ( valor : uint ): void { _color = valor ; } } }                    
var pen : Pen = new Pen (); pen . color = ~ pen . color ; // complemento bit a bit pen . color += 1 ; // suma uno          

Objetivo-C 2.0

@interface  Pen  : NSObject @property ( copy ) NSColor * colour ; // El atributo "copy" hace que se conserve la copia del objeto, en lugar del original. @end   @implementation  Pen @synthesize colour ; // Directiva del compilador para sintetizar métodos de acceso. // Se puede omitir en Xcode 4.5 y versiones posteriores. @end 

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

Pluma * pluma = [ [ Pluma alloc ] init ] ; pluma.color = [ NSColorblackColor ] ; float rojo = pluma.color.redComponent ; [ pluma.color drawSwatchInRect : NSMakeRect ( 0 , 0 , 100 , 100 ) ] ;                

PHP

clase  Pluma {  int privado  $color = 1 ;    función  __set ( $propiedad ,  $valor )  {  si  ( propiedad_existe ( $esta ,  $propiedad ))  {  $esta -> $propiedad  =  $valor ;  }  } función  __get ( $propiedad )  {  si  ( propiedad_existe ( $this ,  $propiedad ))  {  devolver  $this -> $propiedad ;  }  devolver  null ;  } }
$p  =  new  Pen (); $p -> color  =  ~ $p -> color ;  // Complemento bit a bit echo  $p -> color ;

Pitón

Las propiedades solo funcionan correctamente para las clases de estilo nuevo (clases que tienen objectcomo superclase ) y solo están disponibles en Python 2.2 y versiones 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  Pen :  def  __init__ ( self )  ->  None :  self._color = 0  # variable "  privada"  @property  def  color ( self )  : devuelve  self._color @color . setter  def  color ( self ,  color ):  self . _color  =  color
pen  =  Pen () # Accediendo a: pen . color  =  ~ pen . color  # Complemento bit a bit ...

Rubí

clase Pen def initialize @color = 0 fin # Define un captador para el campo @color def color @color fin              # Define un definidor para el campo @color def color= ( valor ) @color = valor fin fin      pluma = Pluma . nuevo pluma . color = ~ pluma . color # Complemento bit a bit     

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

clase 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 definidor para @color (lectura/escritura)           def initialize @color = 0 # Dentro del objeto, podemos acceder directamente a la variable de instancia @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             pen = Pen . new puts pen . brand # Accede a la marca del bolígrafo a través del getter generado pen . size = 0 . 5 # Actualiza el campo de tamaño del bolígrafo a través del setter generado pen . color = ~ pen . color         

Visual Basic

Visual Basic (.NET 2003–2010)

Clase pública Pen Private _color como entero ' Campo privado         Propiedad pública Color () Como entero ' Propiedad pública Obtener Retorno _color Fin Obtener Establecer ( PorVal valor Como entero ) _color = valor Fin Establecer Fin Propiedad                     Fin de clase 
' Crear instancia de clase Pen Dim pen As New Pen ()    ' Establecer valor de lápiz . Color = 1  ' Obtener valor Dim color como Int32 = pen . Color     

Visual Basic (sólo .NET 2010)

Bolígrafo de clase pública   Propiedad pública Color () Como entero ' Propiedad pública     Fin de clase 
' Crear instancia de clase Pen Dim pen As New Pen ()    ' Establecer valor de lápiz . Color = 1  ' Obtener valor Dim color como Int32 = pen . Color     

Visual Basic 6

' en una clase llamada clsPen Private m_Color As Long   Propiedad pública Obtener color () Mientras Color = m_Color Fin de la propiedad         Propiedad pública Let Color ( ByVal RHS As Long ) m_Color = RHS Fin de la propiedad          
'accediendo: Dim pen As New clsPen ' ... pen . Color = No pen . Color       

Véase también

Referencias

  1. ^ "Accessors And Mutators In Java" (Accesores 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::MSPropertyDecl Class Reference". Clang: una interfaz de usuario de la familia de lenguajes C para LLVM . Consultado el 5 de enero de 2022 .
  5. ^ "Extensión de palabra clave __property". Documentación Wiki de Embarcadero/IDERA . Consultado el 5 de enero de 2022 .