Al igual que ocurre con cualquier
otro método, también es posible sobrecargar los constructores. Es decir, se
pueden definir varios constructores siempre y cuando estos tomen diferentes
números o tipos de parámetros. Además, desde el código de un constructor puede
llamarse a otros constructores del mismo tipo de dato antes de ejecutar las
instrucciones del cuerpo del primero. Para ello se añade un inicializador this al constructor, que
es estructura que precede a la llave de apertura de su cuerpo tal y como se
muestra en el siguiente ejemplo:
class A
{
int total;
A(int valor):
this(valor, 2); // (1)
{
}
A(int
valor, int peso) // (2)
{
total
= valor*peso;
}
}
El this incluido hace que
la llamada al constructor (1) de
la clase A provoque una llamada al
constructor (2) de esa misma clase en
la que se le pase como primer parámetro el valor originalmente pasado al
constructor (1) y como segundo
parámetro el valor 2. Es importante señalar que la llamada al constructor (2) en (1) se
hace antes de ejecutar cualquier instrucción de (1)
Nótese que la sobrecarga de
constructores -y de cualquier método en general- es un buen modo de definir
versiones más compactas de métodos de uso frecuente en las que se tomen valores
por defecto para parámetros de otras versiones menos compactas del mismo
método. La implementación de estas versiones compactas consistiría en hacer una
llamada a la versión menos compacta del método en la que se le pasen esos
valores por defecto (a través del this en el caso de los constructores) y si acaso
luego (y/o antes, si no es un constructor) se hagan labores específicas en el
cuerpo del método compacto.
Del mismo modo que en la
definición de un constructor de un tipo de datos es posible llamar a otros
constructores del mismo tipo de datos, también es posible hacer llamadas a
constructores de su tipo padre sustituyendo en su inicializador la palabra
reservada this
por base.
Por ejemplo:
class A
{
int
total;
A(int
valor, int peso)
{
total
= valor*peso;
}
}
class B:A
{
B(int
valor):base(valor,2)
{}
}
En ambos casos, los valores
pasados como parámetros en el inicializador no pueden contener referencias a
campos del objeto que se esté creando, ya que se considera que un objeto no
está creado hasta que no se ejecute su constructor y, por tanto, al llamar al
inicializador aún no está creado. Sin embargo, lo que sí pueden incluir son
referencias a los parámetros con los que se llamó al constructor. Por ejemplo,
sería válido hacer:
A(int x, int y): this(x+y)
{}