domingo, 8 de marzo de 2015

Instancia de un objeto

A veces nos resulta complicado controlar que todos los atributos de todas las clases queden bien instanciados, para tener todo esto mejor controlado lo mejor es tener un diagrama de clases para saber qué clases deben instanciar a qué otras.

A continuación os mostraré lo que puede ocurrir si no tenemos bien controladas todas las instancias.

Tenemos una clase llamada Persona:

using System.IO;
using System;
public class Persona{   

  string nombre;   
  int edad;   
  char sexo;      
  public Persona()   
  {      nombre = "";      
         edad = 0;      
         sexo = ' ';   
  }   
  public Persona(string pNombre, int pEdad, char pSexo)   
  {       nombre = pNombre;
         edad = pEdad;
         sexo = pSexo;   
  }      
  public void imprimir()   
  {      Console.WriteLine("Persona-Nombre: "+nombre);
         Console.WriteLine("Persona-Edad: "+edad);
         Console.WriteLine("Persona-Sexo: "+ sexo);
  }
}

Y tenemos una clase llamada Cliente que incluye a un objeto de tipo Persona, en este caso es Cliente el que debe instanciar al objeto de tipo Persona

using System.IO;
using System;
public class Cliente
{
    int codigo;
    Persona persona;
    
    public Cliente()
    {
        codigo = 0;
        persona = new Persona();//es en el constructor del cliente que instanciamos al objeto de tipo Persona
    }
    public void imprimir()
    {
        Console.WriteLine("Cliente-Codigo: "+codigo);
        persona.imprimir();
    }
}

Si ejecutamos este código:

using System.IO;
using System;

class Program
{
    static void Main()
    {
        Cliente cliente = new Cliente();
        cliente.imprimir();
    }
}

El resultado de la ejecución es la siguiente:
Cliente-Codigo: 0                                                                                                                                                                  
Persona-Nombre:                                                                                                                                                                    
Persona-Edad: 0                                                                                                                                                                    
Persona-Sexo: 

Ahora os mostraré lo que pasaría en el caso que en el constructor de cliente NO se instancie el objeto persona, comentaremos la linea

public Cliente()
    {
        codigo = 0;
        //persona = new Persona();//es en el constructor del cliente que instanciamos al objeto de tipo Persona
    }

El compilador no nos avisará, porque no es un error sintáctico, pero el error vendrá en la ejecución:
Cliente-Codigo: 0                                                                                                                                                                  
                                                                                                                                                                                   
Unhandled Exception:                                                                                                                                                               
System.NullReferenceException: Object reference not set to an instance of an object                                                                                                
  at Cliente.imprimir () [0x00000] in <filename unknown>:0                                                                                                                         
  at Program.Main () [0x00000] in <filename unknown>:0                                                                                                                             
[ERROR] FATAL UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object                                                             
  at Cliente.imprimir () [0x00000] in <filename unknown>:0                                                                                                                         
  at Program.Main () [0x00000] in <filename unknown>:0   

Vemos que Cliente-codigo si que lo ha impreso correctamente, pero a partir de allí la impresión del objeto persona dio error por NULLReference, esto es porque no está instanciado el objeto.

Ahora que hemos visto la importancia de tener controladas las instancias os mostraré como instanciar con valores al objeto persona a partir de la clase Cliente.

Vimos que la clase Persona tiene el constructor:
   public Persona(string pNombre, int pEdad, char pSexo)
   {
       nombre = pNombre;
       edad = pEdad;
       sexo = pSexo;
   }

Agregamos ahora un nuevo constructor a la clase Cliente que utilice este constructor de la clase Persona:
    public Cliente(int pCodigo, string pNombre, int pEdad, char pSexo)
    {
        codigo = pCodigo;
        persona = new Persona(pNombre, pEdad, pSexo);
    }

Y desde el Main le pasamos todos los valores utilizando este nuevo constructor de la clase Cliente:
    static void Main()
    {
        Cliente cliente = new Cliente(1, "Juan", 30, 'H');
        cliente.imprimir();
    }

Y finalmente vemos la ejecución:
Cliente-Codigo: 1                                                                                                                                                                  
Persona-Nombre: Juan                                                                                                                                                               
Persona-Edad: 30                                                                                                                                                                   
Persona-Sexo: H