Вы находитесь на странице: 1из 8

Laherenciadeclases

Como se ha visto anteriormente, todas las clases del Framework .NET provienen de la clase System.Object.La
herenciasepuedeponerenprcticadedosmaneras,laherenciadeclasesylaherenciadeinterfaces.
Laherenciaimplicaqueuntipoderivedeuntipobase,haciendoaccesiblestodossusmiembros.Laherenciaestil
cuando tenga que aadir funcionalidades a un tipo existente, o cuando varios tipos comparten las mismas
funcionalidades.

1.Implementarlaherencia
La declaracin de la herencia utiliza una sintaxis sencilla. Es suficiente con aadir el nombre del tipo base tras el
nombredelaclasederivadayelcarcter:.Unaclasesolopuedederivardeunnicotipobase.
ElmejorejemploeselformularioForm1.cs.
Abraelarchivoeneleditordetextoyobserveladeclaracindelaclase:

public partial class Form1: Form

La clase Form1 deriva de la clase base Form, por lo que Form1 contiene todos los miembros accesibles de su
clasebase.IntelliSensepermiteencontrarlasconfacilidad:

Si no se especifica ninguna clase base, el compilador considera que System.Object es la clase base. De esta
manera,losdosejemplossiguientessonidnticos:

public class Project: System.Object

// Herencia explcita

{
}
public class Project

// Herencia implcita

{
}

Porsimplicidad,laherenciadelaclaseObjectnuncasemarcaexplcitamenteenladefinicindeunaclase.
Los miembros que son accesibles desde la clase derivada son aquellos que tienen un nivel de acceso public,

protectedointernal.Losmiembrosprivados(private)nosernvisiblesporlaclaseheredada.

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

- 1-

2.Losmiembrosvirtuales
Declarando un miembro de la clase base con la palabra reservada

virtual se autoriza al miembro a ser

sobrecargadoporlasclasesderivadas.Estoseaplicaalosmtodosyalaspropiedades:

public class ClaseDeBase


{
public virtual bool PropiedadDeBase { get; set; }
public virtual void MetodoDeBase()
{
}
}

Cuando un mtodo virtual se sobrecarga en una clase derivada, la llamada al mtodo implica la ejecucin del
mtodosobrecargado,yelmtodobasenosellamar.Elmtodosobrecargadosedebedeclararexplcitamente,
usandolapalabrareservadaoverride:

public class ClaseHija: ClaseDeBase


{
public override void MetodoDeBase()
{
}
}

La declaracin del mtodo derivado debe corresponder con la declaracin del mtodo base. En caso contrario el
compilador devolver un error, ya que ver un mtodo con la palabra reservada override, pero no encontrar
ningnmtodocorrespondienteenlaclasebase.

3.Ocultarlosmiembrosheredados
Siunmtododelaclasehijatienelamismadeclaracinqueunmtododelaclasebaseynosedeclaranniconla
palabrareservadavirtual,nioverride,decimosqueelmtodohijoocultaalmtodobase:

public class ClaseDeBase


{
public virtual bool PropiedadDeBase { get; set; }
public void MetodoDeBase()
{
}
}
public class ClaseHija: ClaseDeBase
{
public void MetodoDeBase()
{
}
}

- 2-

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

Durante la compilacin, se da una advertencia que indica al desarrollador que el mtodo oculta el miembro de la
clasebase.Estaadvertenciapermiteclarificarelhechodequeelmtodobasenosellamaryquesisehahecho
demaneraintencionada,hayqueaadirlapalabrareservadanewalmtodohijo:

public new void MetodoDeBase()

Laadvertenciatambinsedesencadenasielmtodobasesemarcacomovirtual,peroelcompiladorsugiereaadir
lapalabrareservadaoverrideenlugardenew.

4.Lapalabrareservadabase
Cuandounmiembrosesobrecarga,elmiembrobaseyanoesaccesibledesdeunainstanciadelaclase,perosigue
siendoaccesibledesdelaclaseheredada,graciasalasintaxisbase.[MetodoDeBase]():

public override void MetodoDeBase()


{
base.MetodoDeBase();
bool b = base.PropiedadDeBase;
}

Puede utilizar esta sintaxis para llamar a cualquier miembro de la clase base en cualquier regin de cdigo de la
clasehija.

5.Lasclasesymiembrosabstractos
El lenguaje C# autoriza a las clases y miembros a ser marcados con la palabra reservada abstract. Una clase
abstracta no se puede instanciar y un mtodo abstracto no contiene implementacin, solo su declaracin. Esto
implica que una clase abstracta solo se puede usar en el marco de la herencia y que la clase derivada debe
implementarlasfuncionalidadesdelosmiembros:

public abstract class ClaseDeBase


{
public abstract bool PropiedadAbstracta { get; set; }
public abstract void MetodoAbstracto();
}

Una clase abstracta tiene como objetivo definir la forma de las clases hijas sin tener que definir el fondo. La
implementacinfinalesresponsabilidaddelaclasehija.
Apartirdelmomentoenelqueunaclasecontieneunmiembroabstracto,statambinseconvierteenabstractay
sedebemarcarcomotal,conlapalabrareservada abstract.Sinembargo,unaclaseabstractapuedecontener
miembrosnoabstractosqueimplementansupropialgica.Estosmiembrosnoabstractostambinpuedenmarcarse
comovirtualesparapodersobrecargarlosacontinuacin.

public abstract class ClaseDeBase


{
public virtual bool PropiedadDeBase { get; set; }

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

- 3-

public abstract bool PropiedadAbstracta { get; set; }


public virtual void MetodoDeBase()
{
}
public abstract void MetodoAbstracto();
}

La clase que hereda de una clase abstracta, debe implementar todos los miembros abstractos con la palabra
reservadaoverride:

public class ClaseHija: ClaseDeBase


{
public override bool PropiedadAbstracta { get; set; }
public override void MetodoAbstracto()
{
}
}

Tambinesposiblecrearunaclasehijaabstractaquederivedeunaclaseabstracta.Entalcaso,noesnecesario
implementartodoslosmiembrosdelaclasepadre:

public abstract class ClaseHija: ClaseDeBase


{
}

6.Lasclasesylosmtodoscerrados
Lapalabrareservadasealedenunadeclaracindeclasepermiteprohibirqueotraclaselaherede.Pordefinicin,
una clase cerrada nunca podr ser abstracta, ya que esos dos modificadores son naturalmente opuestos. De la
mismamanera,losmiembrosnopuedenservirtualesnitenerelmodificadordeaccesoprotected:

public sealed class ClaseDeBase


{
public bool PropiedadDeBase { get; set; }
public void MetodoDeBase()
{
}
}

Una clase no puede ser cerrada y contener miembros que lo sean. Estos miembros, por tanto, no podrn ser
sobrecargadosporlasclaseshijas.Paraasignarelmodificadorsealedaunmiembro,debeheredardeunaclase
base:

public class ClaseDeBase


{
public virtual void MetodoDeBase()
{ }

- 4-

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

}
public class ClaseHija: ClaseDeBase
{
public sealed override void MetodoDeBase()
{ }
}
public class ClaseHija2: ClaseHija
{
public override void MetodoDeBase() // No autorizado
{ }
}

Estopermitedetenerlaherenciadelmiembroyprevenircualquiersobrecargaapartirdelasclaseshijas,aunque
siempreesposiblerealizarunasobrecargaconlapalabrareservadanew:

public class ClaseHija2: ClaseHija


{
public new void MetodoDeBase() // Autorizado
{ }
}

7.Losconstructoresderivados
Una clase hija debe implementar sus propios constructores. Los constructores de la clase base no estn
directamente accesibles fuera de la clase hija. Los constructores predeterminados (sin parmetro) siempre estn
presentesyelconstructorhijoqueimplementasupropioconstructorsinparmetros,nodebehacerexplcitamente
referenciaalconstructorpadreparaquelosdosconstructoresseejecutenempezandoporeldeltipopadre.
Elsiguienteejemplodeclaradosclases.Laclasebasecontieneunaimplementacinespecficaparaelconstructor
sinparmetrosylaclasehijanocontieneningnconstructor:

public class ClaseDeBase


{
public virtual int PropiedadDeBase { get; set; }
public ClaseDeBase()
{
this.PropiedadDeBase = 10;
}
public ClaseDeBase(int i)
{
this.PropiedadDeBase = i;
}
}
public class ClaseHija: ClaseDeBase
{
}

Lainstanciacindeunnuevoobjetosolosepodrhacerconunconstructorsinparmetros:

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

- 5-

ClaseHija este = new ClaseHija(true);

// No autorizado

ClaseHija este = new ClaseHija();

// Autorizado

Como la clase hija no contiene implementacin explcita para el constructor con parmetros, es el constructor sin
parmetrosdelpadreelqueseejecuta.
Si la clase hija implementa su propio constructor de manera predeterminada, la instanciacin de un objeto hijo
implicaraimplcitamentelaejecucindelconstructorpadreydespuseldelconstructorhijo:

public ClaseHija()
{
this.PropiedadDeBase = 5;
}

Despusdelainstanciacin,elmiembroPropiedadDeBasetieneelvalor5:

ClaseHija este = new ClaseHija();

Lapalabrareservadabasepermiteespecificarexplcitamentequconstructordelaclasepadrehayqueejecutary,
deestamanera,modificarestecomportamiento:

public ClaseHija()
: base(5)
{ }

La palabra reservada base se puede usar en todos los constructores de la clase hija, tengan o no parmetros,
para hacer referencia a cualquier constructor de la clase padre. Los parmetros pueden ser valores, como en el
ejemploanterior,oserparmetrosdelconstructorhijo,comoenelsiguienteejemplo:

public ClaseHija(int i)
: base(i)
{ }

Sea cual sea la notacin elegida, el constructor de la clase padre siempre se llamar seleccionando de manera
predeterminada el constructor sin parmetros, si no se especifica otro explcitamente. Adems, los constructores
dentrodeunaherenciasiempreseejecutarndelancestromslejano,hastaelobjetoinstanciado.Estopermite
asegurarlacorrectainicializacindelospadres.

8.Elpolimorfismo
La herencia implica el polimorfismo de las clases. Esto significa que toda clase derivada puede, implcitamente
convertirseenunobjetodesuclasebase.Tomemoscomoejemploestasdosclases:

public class ClaseDeBase


{

- 6-

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

public int PropiedadDeBase { get; set; }


}
public class ClaseHija: ClaseDeBase
{
public int PropiedadHija { get; set; }
}

Es posible declarar e instanciar un objeto del tipo

ClaseHija

y despus asignarlo a un objeto de tipo

ClaseDeBase:

ClaseHija este = new ClaseHija();


ClaseDeBase cb = ce;

Losmiembrosespecficosdelaclasehijayanoestndisponiblesenelobjetodeltipopadre:

int i = cb.PropiedadHija;

// No autorizado

Elobjetonosealteraporlaconversinauntipopadre.Losdatosespecficosdeltipohijosiempreestnpresentes
enmemoria,peronosepuedenexplotar.
Laconversininversa,deltipopadrealtipohijo,sedebehacerdemaneraexplcita:

ce = (ClaseHija)cb;

Silaconversinexplcitafalla,cuandoelobjetoorigennosepuedeconvertiraltipodedestino,durantelaejecucin
seproduceunaexcepcindeltipo InvalidCastException.Paraevitargenerarunaexcepcinenlaejecucin,
laconversinsepuedehacermedianteeloperador as.Elobjetodestinotendrentoncesunareferencianullen
casodeerror:

ce = cb as ClaseHija;

Acontinuacinhayqueprobarsielresultadodelaconversinnoes nullparapoderutilizarelobjetodestinosin
generarerror:

if (ce != null)
{
// La conversin se ha realizado con xito
}

Sinestaprueba,laconversinsineloperadorasesmsventajosa,yaqueelerrorquesedaesmsdescriptivo:

int i = ((ClaseHija)cb).PropiedadHija;
int i = (cb as ClaseHija).PropiedadHija;

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

- 7-

En caso de error, la primera conversin devolver un error del tipo

InvalidCastException, que indica


precisamentequeeslaconversinlaquehafalladoynoquelavariable cb es null.Lasegundaconversin,en
caso de error, devolver una excepcin del tipo NullReferenceException.Estopuedequererdecir,poruna
parte,quelavariablecbnoesdeltipo ClaseHijayquelaconversinhadadounresultado null,porloquela
llamadaalmiembro PropiedadHijadevuelvelaexcepcino,porotraparte,puedequererdecirquelavariable
cbesnull.
Eloperadorispermiteprobareltipodeunobjetoy,enconsecuencia,predecirelresultadodeunaconversin:

ClaseHija ce = new ClaseHija();


ClaseDeBase cb = ce;
if (cb is ClaseDeBase)

// Verdad

{ }
if (cb is ClaseHija)

// Verdad

{ }

Inclusosielobjetoseconvierteasutipopadre,lapruebaconeloperadorisreflejaqueelobjetoestenelorigen
deltipohijo.Estonoescierto,sielobjetosedeclaracomountipopadre:

ClaseDeBase cb = new ClaseDeBase();


if (cb2 is ClaseDeBase)

// Verdad

{ }
if (cb2 is ClaseHija)

// Falso

{ }

- 8-

Editions ENI Tous droits rservs Copie personnelle de Jose Antonio Espino Lopez

Вам также может понравиться