sábado, 6 de septiembre de 2014

10.- Las propiedades


Como ya dijimos, las propiedades es una mezcla entre método y campo, puesto que almacenan valores y además nos permiten hacer cálculos sobre ellos. Para el que accede a la propiedad, la ve como un campo.
Además, son miembros de clase que nos permiten leer, escribir o calcular un campo privado de la clase, es decir, nos permite leerlo, cambiarle su valor o calcularle uno nuevo.
Una propiedad genérica, tiene la siguiente estructura:
  • Contiene un descriptor Get. Se utiliza para leer la propiedad. Una propiedad sin este valor, se considera de solo escritura, puesto que no es posible leerla.
  • Contiene un descriptor Set. Se utiliza para asignar un valor a la propiedad. Si este descriptor no existiera, la propiedad sería solo de lectura y por tanto, sería como cuando vimos la constante, que era un campo de solo lectura.
  • Tiene un campo del mismo tipo que la propiedad y asociado a esta.
Las propiedades no son campos, por tanto no podemos pasar como argumento en un método una propiedad.
¿Qué usos le podemos dar a las variables? Pues podemos usarlas para validar datos antes de permitir un cambio, exponer los datos de forma transparente obtenidos desde otro origen o cuando se realiza una acción, por ejemplo si cambiamos su valor, se genera un evento avisándonos de que la propiedad ha cambiado.
¿Dónde se declaran las propiedades? Las propiedades se declaran a nivel de clase mediante el tipo, el nombre de la propiedad, el descriptor get y el descriptor set.
Ejemplo. En la siguiente propiedad, declaramos un campo month y le asignamos el valor 7. Acto seguido declaramos la propiedad pública Month y en la cual si nosotros solicitáramos su lectura, nos daría el valor del campo month, en este caso, nos daría el valor 7. Si dijéramos que la propiedad Month vale ahora 10 (Octubre), en el descriptor set, comprobaría que el valor que le pasamos es mayor que 0, que como mínimo vale 1 y menor que 13, que como máximo valga 12. Una vez efectuada la comprobación le asignaría el valor a la propiedad. ¿Qué ocurriría si le asignamos el valor 15? Pues como no cumple las condiciones de mayor de 0 y menor de 13 y no se asignaría ningún valor a la propiedad quedando en su estado anterior. El valor value, es el valor que asignamos a la propiedad. ¿bien?
C#
        private int month = 7;  // el campo month
    public int Month        // La propiedad Month
    {
        get
        {
            return month;
        }
        set
        {
            if ((value > 0) && (value < 13))
            {
                month = value;
            }
        }
    }
VB.NET
        Private m_month As Integer = 7' el campo month
        Public Property Month() As Integer' La propiedad Month
            Get
                Return m_month
            End Get
            Set(value As Integer)
                If (value > 0) AndAlso (value < 13) Then
                    m_month = value
                End If
            End Set
        End Property

Otro ejemplo con nuestra clase preferida, la clase Vehiculo. Asignamos un propiedad a esta clase llamada Matricula y otra Potencia, pues vamos a crear una instancia de esta y vamos a leer y escribir sus propiedades.
C#
static void Main(string[] args)
{
            Console.WriteLine ("Comienza la App");
     Vehiculo miVehiculo = new Vehiculo();

            miVehiculo.Potencia = 120;
            miVehiculo.Matricula = "0000 XXX";
            Console.WriteLine(miVehiculo.Potencia);
            Console.WriteLine(miVehiculo.Matricula);
            Console.WriteLine("Pulse INTRO para finalizar..");
            Console.ReadLine();
}
class Vehiculo
{
        public Vehiculo()
        {
            // código utilizado al instanciar la clase
        } 
        private double _potencia;  
        public double Potencia
        {
            get { return _potencia; }
            set { _potencia = value; }
        }
        private string _matricula;
        public string Matricula
        {
            get { return _matricula; }
            set { _matricula = value; }
        }
}
VB.NET
        Private Shared Sub Main(args As String())
            Console.WriteLine("Comienza la App")
            Dim miVehiculo As New Vehiculo()
            miVehiculo.Potencia = 120
            miVehiculo.Matricula = "0000 XXX"
            Console.WriteLine(miVehiculo.Potencia)
            Console.WriteLine(miVehiculo.Matricula)
            Console.WriteLine("Pulse INTRO para finalizar..")
            Console.ReadLine()
        End Sub 
        Private Class Vehiculo
            ' código utilizado al instanciar la clase
            Public Sub New()
            End Sub 
            Private _potencia As Double
            Public Property Potencia() As Double
                Get
                    Return _potencia
                End Get
                Set(value As Double)
                    _potencia = value
                End Set
            End Property 
            Private _matricula As String
            Public Property Matricula() As String
                Get
                    Return _matricula
                End Get
                Set(value As String)
                    _matricula = value
                End Set
            End Property
        End Class 
En este ejemplo, desde el método de clase Main, creamos un objeto Vehículo llamado miVehiculo, le asignamos a la propiedad Potencia un valor de 120 , a la propiedad de Matrícula 0000 XXX y una vez asignadas, las imprimimos por pantalla.
¿Qué ocurre dentro de las propiedades? Cuando le asignamos un valor a la Propiedad Potencia, estamos accediendo al descriptor set dándole al valor del campo _potencia, el valor asignado de 120 pero en el siguiente paso, cuando lo imprimimos por pantalla accedemos al descriptor get y este lo que hace es ir a buscar el campo privado de clase _potencia y devuelve su valor que es 120. Así de fácil.
Otro ejemplo un poco más complejo.
C#
class Cuadrado
    {
        public double _lado;
        public Cuadrado(double s)  //constructor
        {
            _lado = s;
        }
        public double Area
        {
            get
            {
                return _lado * _lado;
            }
            set
            {
                _lado = System.Math.Sqrt(value);
            }
        }       
        public double Volumen
        {
            get
{ return _lado * _lado * _lado; }
            set
{ _lado =System.Math.Pow( value, 1 / 3); }
       } 
static void Main(string[] args)
{
      Cuadrado MiCuadrado = new Cuadrado(4);
      Console.WriteLine(MiCuadrado.Area); // imprime por pantalla 16
      MiCuadrado.Area = 100; // ahora el lado vale 10, pero no lo vemos porque es un camp privado de clase
          Console.WriteLine(MiCuadrado.Volumen); // imprime por pantalla 1000
 }

VB.NET
Class Cuadrado
        Public _lado As Double
        Public Sub New(s As Double)
            'constructor
            _lado = s
        End Sub 
        Public Property Area() As Double
            Get
                Return _lado * _lado
            End Get
            Set(value As Double)
                _lado = System.Math.Sqrt(value)
            End Set
        End Property
        Public Property Volumen() As Double
           Get
                Return _lado * _lado * _lado
           End Get
           Set(value As Double)
               _lado = System.Math.Pow(value, 1 \ 3)
           End Set
        End Property
End Class
 
Private Shared Sub Main(args As String())
Dim MiCuadrado As New Cuadrado(4)
            Console.WriteLine(MiCuadrado.Area)
            ' imprime por pantalla 16
            MiCuadrado.Area = 100
            ' ahora el lado vale 10, pero no lo vemos porque es un camp privado de clase
End Sub
Creamos una clase Cuadrado a la cual le agregamos una propiedad llamada Area con un campo llamado _lado. En el constructor de la clase, (lo primero que hace una clase cuando se instancia), le agregamos un parámetro s, de modo que cuando instanciemos la clase Cuadrado, nos pedirá que le pasemos un argumento, en este caso el valor del lado el cual automáticamente es asignado al campo _lado. Hasta aquí todo bien.
Si le pedimos al objeto cuadrado el valor de su Area, el descriptor get, obtendrá el valor de _lado y lo multiplicará por si mismo, obteniendo el Area que solicitamos.
Si ahora le dijéramos a este objeto que el valor de su Area es 100, el descriptor set calcularía la raíz cuadrada del área para asignar al campo _lado este valor, en este caso 10, por tanto al solicitarle que imprima por pantalla la propiedad Volumen, este ha calculado el nuevo valor del lado y el nuevo valor del volumen. Este es uno de los poderes secretos de las propiedades. Fantástico ¿no?
Ahora que sabemos que son las propiedades, más adelante crearemos algunas más complejas que nos avisen cuando cambie su valor generando eventos.
Saludos “der Waki”

 

No hay comentarios:

Publicar un comentario