Está en la página 1de 127

Programacinorientadaa

objetosenJava

Programacinorientadaa
objetosenJava
1.Clasesdeobjetos
2.Proteccindemiembros
3.Proteccindeclases
4.Inicializacinyfinalizacin
5.Creacindeobjetos
6.Trabajandoconobjetos
7.Relacionesentreobjetos
8.Clasesanidadaseinteriores
9.Autoreferencias
10.Aplicacionesorientadasaobjetos
11.Herencia
12.Adicin,redefinicinyanulacin
13.Proteccinyherencia

14.Herenciamltiple
15.Polimorfismo
16.Ligaduradinmica
17.Informacindeclasesentiempo
deejecucin
18.OtrostemasdeintersenJava

Programacinorientadaa
objetosenJava

Clasesdeobjetos
Lasclasesdeobjetosrepresentanconceptoso
entidadessignificativosenunproblemadeterminado.
Unaclasedescribelascaractersticascomunesdeun
conjuntodeobjetos,mediantedoselementos:

Atributos(ovariablesmiembro,variablesdeclase).Describenelestadointerno
decadaobjeto
Operaciones(omtodos,funcionesmiembro).Describenloquesepuedehacer
conelobjeto,losserviciosqueproporciona
Cuenta

Atributos

Operaciones

Nombredelaclase

nmero:String
titular:String
saldo:Float
interesAnual:Float
ingreso(cantidad:Floatl)
reintegro(cantidad:Floatl)
ingresoInteresMes()
enRojos():Boolean
leerSaldo():Real

Clasesdeobjetos

Programacinorientadaa
objetosenJava

Durantelaejecucindelaaplicacinseproducirla
instanciacindelaclase,esdecir,lacreacindelos
objetosquerepresentancadaunodelosindividuos
consuscaractersticaspropias,esdecir,valores
especficosparasusatributos

c:Cuenta
Cuenta
nmero:String
titular:String
saldo:Float
interesAnual:Float
ingreso(cantidad:Floatl)
reintegro(cantidad:Floatl)
ingresoInteresMes()
enRojos():Boolean
leerSaldo():Real
Clasedeobjetos

numero=123890023
titular=MiguelPrez
saldo=1800.4
intersAnual=0.25

e:Cuenta
numero=151590020
titular=Javier
Snchez
saldo=1200.2
intersAnual=1.25

d:Cuenta
numero=23900839
titular=Antonio
Gmez
saldo=200
intersAnual=0.25
Objetos

Clasesdeobjetos

Programacinorientadaa
objetosenJava

LaimplementacindeestaclaseenJavaserealizaraenunficheroconnombre
Cuenta.java,ysucontenidoseraelsiguiente:

Atributos

Operaciones

classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;

voidingreso(floatcantidad){}
voidreintegro(floatcantidad){}
voidingresoInteresMes(){}
booleanenRojos(){}
floatleerSaldo(){}
}

Losatributospuedenserdecualquieradelostipos
bsicosdeJava:boolean,char,byte,short,int,long,
floatydouble,referenciasaotrosobjetosoarrays
deelementosdealgunodelostiposcitados

Clasesdeobjetos

Programacinorientadaa
objetosenJava

AlcontrarioqueC++,Javarealizaladefinicine
implementacindelaclaseenelmismolugar,enun
nicofichero.java

classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;

voidingreso(floatcantidad){
saldo+=cantidad;
}
voidreintegro(floatcantidad){
saldo=cantidad;
}
voidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
booleanenRojos(){returnsaldo<0;}
floatleerSaldo(){returnsaldo;}
}
Clasesdeobjetos

Programacinorientadaa
objetosenJava

Elaccesoalosatributosdelaclasedesdela
implementacindelasoperacionesserealizade
formadirecta
Losatributosuoperacionesestticas(static)noson
afectadosporelprocesodeinstanciacindeobjetos
apartirdelaclase
Deunatributoestticonosegeneraunacopiapor
cadaobjetoquesecrea.Existeunanicacopia
compartidayaccesibledesdetodoslosobjetosdela
clase
Unaoperacinestticanicamentepuedeaccedera
miembrosestticos

Clasesdeobjetos

Programacinorientadaa
objetosenJava

ElatributonOpmantieneunacuentaglobaldelnmerodeoperaciones
realizadasenlascuentasdelbanco,paralarealizacindeestadsticas.La
operacinleerNOperaciones()permiteleerestecontador
LaoperacineurosAPesetas()esunaoperacinauxiliardelaclaseCuentapara
serusadacuandoseanecesariaunaconversindemoneda
classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;

//Contadordeoperaciones
staticintnOp=0;
staticintleerNOperaciones(){returnnOp;}
//Operacinestticaauxiliardeconversin
staticlongeurosAPesetas(floateuros){returneuros*166.386f;}
voidingreso(floatcantidad){saldo+=cantidad;++nOp;}
voidreintegro(floatcantidad){saldo=cantidad;++nOp;}
}

Clasesdeobjetos

Programacinorientadaa
objetosenJava

Proteccindemiembrosdelaclase
Elprincipiodeocultacindeinformacinseplasma
enloslenguajesOOendiversosmecanismosde
proteccindelosmiembrosdelaclase
UMLpermiteasociartresnivelesdeproteccin
diferentesacadamiembrodelaclase:

Miembrospblicos(+).Sinningntipodeproteccinespecial
Miembrosprivados().Inaccesiblesdesdeelexteriordelaclase
Miembrosprotegidos(#).Similaresalosprivadosaunquesepermitesuacceso
desdelasclasesdescendientes*

Clase
atributoPrivado:Tipo
+atributoPublico:Tipo
#atributoProtegido:Tipo
operacionPrivada()
+operacionPublica()
#operacionProtegida()

*Lasveremosmsadelante,alestudiarelmecanismodelaherencia

Proteccinde
miembros

Programacinorientadaa
objetosenJava

EnJavaunmiembroseetiquetacomopblicocolo
candoelidentificadorpublicdelantedesudeclaracin
Paralosmiembrosprivadosutilizaremosel
identificadorprivate

Cuenta
numero:Long
titular:String
saldo:Float
intersAnual:Real
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer

classCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;

publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Proteccinde
miembros

Programacinorientadaa
objetosenJava

Losmiembrosnoetiquetadossonaccesiblesporparte
declasesamigas.EnC++yotroslenguajesOOlas
clasesamigasaunadadapuedenindicarse
explcitamente
EnJavaseconsideranamigastodasaquellasque
formanpartedelmismopaquete

Unficherofuentejavaformaensunpaqueteyportantotodaslasclasesincluidas
enlsonamigas
Lasclasesincluidasenvariosficherosfuentepuedenagruparseenunnico
paqueteindicandoelnombredepaquetealprincipiodecadaficheromedianteel
indicadorpackage
packageprueba;

packageprueba;

classA{
...
}

classC{
...
}

classB{
...
}

classD{
...
}
classE{
...
}

LasclasesA,ByCsonamigasalpertenecer
almismopaqueteprueba
LasclasesDyEsonamigasalperteneceral
mismoficherofuente

Proteccinde
miembros

Programacinorientadaa
objetosenJava

Enesteejemplo,lasclasesCuentayBancosonamigasalperteneceralmismo
ficherofuente.ElaccesoalosatributosdelosobjetosdelaclaseCuentaalmacenados
enelvectorinternodeBancoquedaasgarantizado.Elatributosaldopuede
mantenersecomoprivadopuestoqueexisteunaoperacinquepermiteobtenersu
valor:
classCuenta{
longnumero;
Stringtitular;
privatefloatsaldo;
floatinteresAnual;

publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
classBanco{
Cuenta[]c;//vectordecuentas
...
}

Proteccinde
miembros

Programacinorientadaa
objetosenJava

Atencin:todaslasclasesquenosedeclarencomo
pertenecientesaningnpaquetedeformaexplcita,
pertenecenaunpaquetepordefectoyportantoson
amigas
Unpaquetecreaunespaciodenombrespropios.Esto
significaquelaclasepasaatenercomoprefijoel
propionombredelpaquete.Alahoradeutilizarla
tenemostresopciones:

Utilizarsunombrecompleto:prueba.A
Importaresaclase,parapoderutilizarlasinelprefijo.Estoseindicaalprincipiodel
cdigofuentemedianteimportprueba.A
Importardirectamentetodaslasclasesdelpaquete,queseusaransinprefijo:
importprueba.*

Proteccinde
miembros

Programacinorientadaa
objetosenJava

Unpaquetepuedeestarsituadodentrodeotro
paqueteformandoestructurasjerrquicas.Ejemplo:
miapp.prueba.A
Javaobligaaqueexistaunacorrespondenciaentrela
estructuradepaquetesdeunaclaseylaestructurade
directoriosdondeestsituada
Laraizdelaestructuradedirectoriosdebeestar
incluidaenelclasspathdeJava(parmetrocp<dir>)

Lasclasesmiapp.prueba.A,miapp.prueba.Bymiapp.Cdebenestarenlasiguiente
estructuradedirectorios:

miapp

prueba
C

A
B
Proteccinde
miembros

Programacinorientadaa
objetosenJava

Proteccindeclases
Porproteccindeclasesentendemosunnivelsuperior
delaocultacindeinformacin,aniveldeclases.Es
decir,setratadeespecificarqueclasespuedenser
utilizadasycualesno,yporquin
Dentrodeunpaquete,lasclasessonamigasypor
tantonoexistenrestriccionesrespectoalautilizacin
deunaclaseporlasotras
Sinembargo,desdeelpuntodevistadelexterior,
nicamentepodrnserutilizadaslasclasespblicas
delpaquete,esdecir,aquellasconelidentificador
publicsituadodelantedesudeclaracin

Proteccindeclases

Programacinorientadaa
objetosenJava

Atencin:Javaslopermiteunaclasepblicapor
ficherofuente,yelnombredelaclaseyelfichero
debencoincidirobligatoriamente

Ennuestroejemplo,siqueremosquelaclaseCuentapuedaserutilizadadesdeel
exteriordelficheroCuenta.javadeberemosdeclararlacomopblica
publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;

publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}

Proteccindeclases

Programacinorientadaa
objetosenJava

Inicializacinyfinalizacin
Lainiciacindelosatributosdelaclaseserealizaen
Java,aligualqueenC++,medianteelusode
constructorescuyonombrecoincideconeldelaclase

publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
Cuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Javapermitelasobrecargadeoperaciones,portanto
sepuedendefinirvariosconstructoresposibleparauna
clasesiemprequesediferencienenlalistade
argumentos

//Importartodaslasclasesdelpaquetejava.io
importjava.io.*;
publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
//Constructorgeneral
Cuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

//Constructorparaobtenerlosdatosdelacuentadeunfichero
Cuenta(longaNumero)throwsFileNotFoundException,IOException,
ClassNotFoundException{

FileInputStreamfis=newFileInputStream(aNumero+.cnt);
ObjectInputStreamois=newObjectInputStream(fis);
numero=aNumero;
titular=(String)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
ois.close();
}
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Nota:vaseelapartadoI/O:ReadingandWritingdeltutorialJavadeSuncomoapoyoparaentender
elcdigodelnuevoconstructor

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Sinoseproporcionaningnconstructor,Java
proporcionaautomticamenteunconstructorpor
defecto,quenorecibeargumentosyrealizauna
inicializacinpordefectodelosatributos
Unavezimplementadounconstructorpropioporparte
delprogramador,Javaeliminadichoconstructor,
aunquepuedeserdefinidonuevamentedemanera
explcita

Cuenta(){
numero=00000000;
titular=ninguno;
saldo=0;
interesAnual=0;
}
Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Naturalmentelosconstructorespuedensermarcados
comopblicos,privados,protegidosoconaccesoa
niveldepaquete,loqueespecificarquienpuedecrear
objetosdeestaclaseydequemanera

//Constructorgeneral
publicCuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
//Constructorparaobtenerlosdatosdelacuentadeunfichero
publicCuenta(longaNumero)throwsFileNotFoundException,
IOException,ClassNotFoundException{
FileInputStreamfis=newFileInputStream(aNumero+.cnt);
ObjectInputStreamois=newObjectInputStream(fis);
numero=aNumero;
titular=(String)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
ois.close();
}

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Cuandofinalizaelusodeunobjeto,esfrecuentela
realizacindeciertastareasantesdesudestruccin,
principalmentelaliberacindelamemoriasolicitada
durantesuejecucin.EstoserealizaenC++yotros
lenguajesOOenlosdenominadosdestructores
Estosdestructoressonoperacionesinvocadas
automticamentejustoantesdeladestruccindel
objeto
Sinembargo,enJavalaliberacindememoriase
realizademaneraautomticaporpartedelrecolector
debasura,portantolanecesidaddeestetipode
operacionesnoexisteenlamayorpartedeloscasos

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Sinembargospuedesernecesariorealizaralguna
tareanorelacionadaconlaliberacindememoria
antesdeladestruccindelobjeto,comoporejemplo
salvarelestadodelaclaseenunficheroobasede
datos
Javapermiteintroducircdigoparaestefin
implementandounaoperacinpblicaespecial
denominadafinalize.Estaoperacinesinvocada
automticamenteantesdeladestruccindelobjetopor
partedelrecolectordebasura

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Siguiendonuestroejemplo,vamosasegurarnosdequeelestadodeunacuenta
quedasalvadoendiscoantesdesudestruccin,parapoderserrecuperada
posteriormente.Paraellointroducimoselcdigodeescrituraenficheroenla
operacinfinalizedelaclaseCuenta
publicvoidfinalize():throwsFileNotFoundException,IOException{

FileOutputStreamfos=newFileOutputStream(numero+.cnt);
ObjectOutputStreamoos=newObjectOutputStream(fos);
oos.writeObject(titular);
oos.writeFloat(saldo);
oos.writeFloat(interesAnual);
oos.close();
}

Problema:noesposiblesaberconseguridadenque
momentoserinvocadafinalize,puestoqueel
recolectordebasurapuededecidirsueliminacinenun
momentoindeterminado,einclusonosereliminado
hastaelfinaldelaejecucindelaaplicacin
Inicializaciny

finalizacin

Programacinorientadaa
objetosenJava

Unaposiblesolucinesordenaralrecolectorde
basuraquerealiceunalimpiezadememoriainmediata,
paraasegurarlafinalizacindelosobjetos.Estose
realizamedianteRuntime.getRuntime().gc()
Pormotivosdeeficiencia,loanteriorespoco
recomendable,sobretodosisehaceconfrecuencia
Unamejoropcinesdefinirunaoperacinordinaria
conestemismopropsito,allamardemaneraexplcita
cuandohayafinalizadoelusodelobjeto

IntroduciremosenlaclaseCuentaunaoperacinpblicasalvarenlugardefinalize,
conlamismaimplementacin.Trasfinalizarlasoperacionessobrelacuenta,
invocaremosasalvarparaguardarloscambiosrealizados

Inicializaciny
finalizacin

Programacinorientadaa
objetosenJava

Creacindeobjetos
EnJavalosobjetossecreannicamentedeforma
dinmica.Paraelloseutilizaeloperadornew,de
manerasimilaraC++
LosobjetosenJavaseutilizansiempreatravsde
referencias.Lasreferenciassonsimilaresalos
punterosdeC/C++,aunquesuusoesmuchoms
sencillo
Portantolospasosaseguirenlacreacindeun
objetoson:

Declararunareferenciaalaclase
Crearunobjetomedianteeloperadornewinvocandoalconstructoradecuado
Conectarelobjetoconlareferencia
Creacindeobjetos

Programacinorientadaa
objetosenJava

LacreacindeunobjetodelaclaseCuentaserealizaradelasiguienteforma:
Cuentac;//UnareferenciaaunobjetodelaclaseCuenta
c=newCuenta(18400200,PedroJimnez,0.1f);

Encambio,lostiposbsicos(int,long,float,etc.)s
puedensercreadosdirectamenteenlapila.Estoes
posibleporqueJavanolosimplementarealmentecomo
clasesdeobjetos,pormotivosdeeficienciay
comodidad,yaquesuusoesmuyfrecuente

Cuentac;
floatin;
longnum;
in=0.1f;
num=18400200;
c=newCuenta(num,PedroJimnez,in);
Creacindeobjetos

Programacinorientadaa
objetosenJava

Lascadenasdecaracteresseimplementanconuna
clase(String).Sinembargonosuelesernecesariasu
creacindemaneraexplcita,yaqueJavalohacede
maneraautomticaalasignarunacadenaconstante*

Strings;//UnareferenciaaunobjetodelaclaseString
//ConexindelareferenciasconunobjetoString
//creadodinmicamenteeinicializadoconlaconstantePedro
s=Pedro;
//Seraequivalentea:
//char[]cc={'P','e','d','r','o'}
//s=newString(cc);

Losarraystambindebensercreadosdinmicamente
connewcomosifueranobjetos

int[]v;//Unareferenciaaunvectordeenteros
v=newint[10]//Creacindeunvectorde10enteros

*VaseelapartadoCharactersandStringsdeltutorialdeJavadeSunparamsinformacin

Creacindeobjetos

Programacinorientadaa
objetosenJava

Sielarrayesdereferenciasaobjetos,habrquecrear
ademscadaunodelosobjetosreferenciadospor
separado

Cuenta[]v;//UnvectordereferenciasaobjetosdelaclaseCuenta
intc;
v=newCuenta[10]//Crearespaciopara10referenciasacuentas
for(c=0;c<10;c++)
v[c]=newCuenta(18400200+c,Clienten.+c,0.1f);

Ladestruccindelosobjetosserealizademanera
automticacuandoelrecolectordebasuradetectaque
elobjetonoestsiendousado,esdecir,noest
conectadoaningunareferencia

Cuentac1=newCuenta(18400200,Cliente1,0.1f);
Cuentac2=newCuenta(18400201,Cliente2,0.1f);
c1=c2
//Elobjetoasociadoalacuenta18400200ha
//quedadodesconectadoysereliminadoporel
//recolectordebasura

Creacindeobjetos

Programacinorientadaa
objetosenJava

Trabajandoconobjetos
TrabajarconunobjetoJavaessimilaraC++,aunque
lasreferenciaspermitenunusomuchomssencillo

Cuentac1=newCuenta(18400200,PedroJimnez,0.1f);
Cuentac2=newCuenta(18400201);
c2.reintegro(1000);
c1.ingreso(500);
if(c2.enRojos())
System.out.println(Atencin:cuenta18400201ennmerosrojos);
System.out.println(Saldoactualdelacuenta18400201:+c1.leerSaldo());
c1=newCuenta(18400202);
//ElobjetoasociadoalaCuenta18400200quedadesconectado
c1.ingreso(500);
System.out.println(Saldoactualdelacuenta18400202:+c1.leerSaldo());

Trabajandocon
objetos

Programacinorientadaa
objetosenJava

Enesteejemplosepideunnmerodecuentaalusuarioyunacantidadaretirar.A
continuacinsecargalacuentasolicitadayserealizaelreintegro
BufferedReaderbr=newBufferedReader(InputStreamReader(System.in));
longnc;
floatmi;
try{
System.out.println(Introduzcanm.dedecuenta:);
nc=Long.parseLong(br.readLine());
System.out.println(Introduzcaimportearetirar:);
mi=Float.parseFloat(br.readLine());
}
catch(Exceptione){
System.out.println(Erroralleerdatos);
return;
}
Cuentac;
try{
c=newCuenta(nc);
}
catch(Exceptione){
System.out.println(Imposiblerecuperarcuenta);
return;
}
if(c.leerSaldo()<mi)
System.out.println(Saldoinsuficiente);
else
c.reintegro(mi);
c.salvar();
Trabajandocon
objetos

Programacinorientadaa
objetosenJava

Naturalmenteelcompiladorproducirunerrorante
cualquieraccesoilegalaunmiembrodelaclase

Cuentac=newCuenta(18400200,PedroJimnez,0.1f);
c.saldo=1000;
Cuenta.java:XX:saldohasprivateaccess
c.saldo=1000;
^
1error

Elaccesoaunmiembroestticoserealizautilizando
elnombredelaclaseenlugardeunobjeto

Cuentac=newCuenta(18400200,Cliente1,0.1f);
c.ingreso(1000);
intpts=Cuenta.eurosAPesetas(c.leerSaldo());
System.out.println(Saldo:+c.leerSaldo()+(+pts+pesetas);
Trabajandocon
objetos

Programacinorientadaa
objetosenJava

Relacionesentreobjetos
Unconjuntodeobjetosaisladostieneescasa
capacidadpararesolverunproblema.Enuna
aplicacinreallosobjetoscolaboraneintercambian
informacin,existiendodistintostiposderelaciones
entreellos
Aniveldediseo,podemosdistinguirentre5tiposde
relacionesbsicasentreclasesdeobjetos:
dependencia,asociacin,agregacin,composiciny
herencia*

*Laveremosmsadelante,enunapartadoespecfico

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Ladependenciaeslarelacinmenosimportante.
Simplementereflejaquelaimplementacindeuna
clasedependedeotra
Unadependenciapuedeindicarlautilizacindeun
objetodeunaclasecomoargumentodeunaoperacin
deotraoensuimplementacin

Comovimosanteriormente,laclaseCuentarequierelasclasesFileOutputStreamy
ObjectOutputStreamdelalibreradeclasesdeJavaparalaimplementacindela
operacinsalvar
Cuenta
numero:Long
titular:String
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+salvar()

java.io.FileOutputStream
java.io.ObjectOutputStream

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Encambio,laasociacineslarelacinmsimportante
ycomn.Reflejaunarelacinentredosclases
independientesquesemantienedurantelavidadelos
objetosdedichasclasesoalmenosduranteuntiempo
prolongado
EnUMLsueleindicarseelnombredelarelacin,el
sentidodedicharelacinylascardinalidadesenlos
dosextremos

VamosasustituirelatributotitularporunaasociacinconunanuevaclaseCliente
completa
Cuenta
numero:Long
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+leerTitular():Cliente
+salvar()

Cliente
titular
*

nombre:String
apellidos:String
direccin:String
localidad:String
fNacimiento:Date
+nombreCompleto():String
+direccionCompleta():String

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

UnaasociacinseimplementaenJavaintroduciendo
referenciasaobjetosunaclasecomoatributosenla
otra
Silarelacintieneunacardinalidadsuperiorauno
entoncessernecesarioutilizarunarrayde
referencias.Tambinesposibleutilizarunaestructura
dedatosdinmicadelpaquetejava.utilcomoVectoro
LinkedListparaalmacenarlasreferencias
Normalmentelaconexinentrelosobjetosserealiza
recibiendolareferenciadeunodeellosenel
constructorounaoperacinordinariadelotro

Relacionesentre
objetos

publicclassCliente{
privateStringnombre,apellidos;
privateStringdireccion,localidad;
privateDatefNacimiento;

Programacinorientadaa
objetosenJava

Cliente(StringaNombre,StringaApellidos,StringaDireccion,
StringaLocalidad,DateaFNacimiento){
nombre=aNombre;
apellidos=aApellidos;
direccion=aDireccion;
localidad=aLocalidad;
fNacimiento=aFNacimiento;
}
StringnombreCompleto(){returnnombre++apellidos;}
StringdireccionCompleta(){returndireccion+,+localidad;}
}

publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
ClienteleerTitular(){returntitular;}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Laagregacinesuntipoespecialdeasociacindonde
seaadeelmatizsemnticodequelaclasededonde
partelarelacinrepresentaeltodoylasclases
relacionadaslaspartes
RealmenteJavaylamayoradelenguajesorientados
aobjetosnodisponendeunaimplementacinespecial
paraestetipoderelaciones.Bsicamentesetratan
comolasasociacionesordinarias

Polgono

Departamento

formadopor
2

Segmento

disponede
1

Despacho

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Lacomposicinesuntipodeagregacinqueaadeel
matizdequelaclasetodocontrolalaexistenciadelas
clasesparte.Esdecir,normalmentelaclasetodo
crearalprincipiolasclasesparteyalfinalse
encargardesudestruccin

SupongamosqueaadimosunregistrodemovimientosalaclaseCuenta,deforma
quequedeconstanciatrascadaingresooreintegro
Cuenta
numero:Long
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+leerTitular():Cliente
+salvar()

Cliente
titular
*

nombre:String
apellidos:String
direccin:String
localidad:String
fNacimiento:Date
+nombreCompleto():String
+direccionCompleta():String

registra

Movimiento
*

fecha:Date
tipo:Char
importe:Real
saldo:Real

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Lascomposicionestienenunaimplementacinsimilar
alasasociaciones,conladiferenciadequeelobjeto
principalrealizarenalgnmomentolaconstruccinde
losobjetoscompuestos

importjava.util.Date
classMovimiento{
Datefecha;
chartipo;
floatimporte;
floatsaldo;
publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldo=aSaldo;
}
}

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
privateLinkedListmovimientos;//Listademovimientos

//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Nuevaimplementacindeingresoyreintegro
publicvoidingreso(floatcantidad){
movimientos.add(newMovimiento(newDate(),'I',cantidad,saldo+=cantidad));
}
publicvoidreintegro(floatcantidad){
movimientos.add(newMovimiento(newDate(),'R',cantidad,saldo=cantidad));
}

publicvoidingresoInteresMes(){ingreso(interesAnual*saldo/1200);}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu

Nota:tambinseranecesariomodificarelotroconstructorylaoperacinsalvarparatenerencuentalalistademovimientos
alahoradeleer/escribirlainformacindelaCuentaendisco

Relacionesentre
objetos

Programacinorientadaa
objetosenJava

Clasesanidadaseinteriores
JavayalgunosotroslenguajesOOPpermitenla
definicindeunaclasedeobjetosdentrodeotra,con
unadobleutilidad:

Organizarmejorelcdigo.Empaquetarenunaclaseprincipalotrasquenotienen
utilidadosentidofueradelcontextodesta
Evitarcolisionesdenombres.Laclaseprincipaldefineunespaciodenombresalque
pertenecenlasanidadas

Aligualquecualquierotromiembrodeunaclase,una
claseanidadapuedeserestticaonoestticayutilizar
losnivelesdeproteccinpublic,privateyprotected
Eltipodeclaseanidamientomssencilloesaquelen
quelaclasecontenidasedeclaracomoesttica

Clasesanidadase
interiores

Programacinorientadaa
objetosenJava

Desdeelpuntodevistadelaorganizacindelcdigo,tendramuchomssentido
introducirlaclaseMovimientoenelinteriordeCuenta.Alserdeclaradacomoprivada,
seimpedirasuutilizacindesdeelexterior
importjava.util.Date
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
privateLinkedListmovimientos;//Listademovimientos
staticprivateclassMovimiento{
Datefecha;
chartipo;
floatimporte;
floatsaldo;
publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;tipo=aTipo;importe=aImporte;saldo=aSaldo;
}
}
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Clasesanidadase
interiores

Programacinorientadaa
objetosenJava

Cuandolaclaseanidadanoesesttica,sedenomina
claseinteriorytienecaractersticasespeciales:

Puedensercreadasnicamentedentrodelaclasecontinente
Tieneaccesocompletoydirectoatodoslosatributosyoperacionesdelobjetoque
realizasucreacin

Losobjetosdelaclaseinteriorquedanligados
permanentementealobjetoconcretodelaclase
continentequerealizsucreacin
Nodebeconfundirseesteelementoconlarelacinde
composicin,aunqueenmuchoscasosesposible
utilizarclasesinterioresparalaimplementacindeeste
tipoderelaciones

Clasesanidadase
interiores

Programacinorientadaa
objetosenJava

ImplementandolaclaseMovimientocomounaclaseinterioresposiblecopiarel
valordelsaldoactualdelacuentaquerealizaelmovimientodemaneradirecta
importjava.util.Date
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;
privateLinkedListmovimientos;//Listademovimientos
privateclassMovimiento{
Datefecha;
chartipo;
floatimporte,saldoMov;
publicMovimiento(DateaFecha,charaTipo,floataImporte){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldoMov=saldo;//Copamoselsaldoactual
}
}
//SiguelaimplementacindelaclaseCuenta

Clasesanidadase
interiores

Programacinorientadaa
objetosenJava

//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;
interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Nuevaimplementacindeingresoyreintegro
publicvoidingreso(floatcantidad){
saldo+=cantidad;
movimientos.add(newMovimiento(newDate(),'I',cantidad));
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
movimientos.add(newMovimiento(newDate(),'R',cantidad));
}

publicvoidingresoInteresMes(){ingreso(interesAnual*saldo/1200);}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}

Clasesanidadase
interiores

Programacinorientadaa
objetosenJava

Autoreferencias
Enocasionesesnecesarioobtenerunareferenciaen
laimplementacindeunaoperacinalpropioobjeto
sobreelquehasidoinvocadalaoperacin
EstareferenciaseobtieneenC++yJavamedianteel
operadorthis
Cuandoencontremosthisenunaexpresin,podremos
sustituirlomentalmenteporesteobjeto
Aunquenoesnecesario,podemosutilizarthispara
llamardesdelaimplementacindeunaoperacina
otraoperacindelmismoobjeto

Autoreferencias

Programacinorientadaa
objetosenJava

LallamadaalaoperaciningresodesdeingresoInteresMes()puederealizarse
utilizandothiscomoreferenciadelobjetosobreelqueseinvocalaoperacin
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;

publicvoidingresoInteresMes(){this.ingreso(interesAnual*saldo/1200);}
//RestodelasoperacionesdelaclaseCuenta

Enesteejemplo,elusodethisesrealmentetil.Nospermiteimplementarla
operacintransferirDesde()llamandoaunaoperacintransferirHasta(),previamente
implementada
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;

publicvoidtransferirHasta(Cuentac,floatcant){
reintegro(cant);c.ingreso(cant);
}
publicvoidtransferirDesde(Cuentac,floatcant){
c.transferirHasta(this,cant);
}
//RestodelasoperacionesdelaclaseCuenta

Autoreferencias

Programacinorientadaa
objetosenJava

OtrautilidaddethisenJavaesrealizarunallamadaa
unconstructordesdeotroconstructor

publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;

//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Constructorespecficoparacuentasdeahorro(interesAnual=0.1%)
publicCuenta(longaNumero,ClienteaTitular){
this(aNumero,aTitular,0.1);
}
//RestodelaclaseCuenta

Peroatencin:unconstructornoesunaoperacin
ordinaria.nicamentepuedellamarseaunconstructor
desdeotroconstructorydebeserlaprimerainstruccin
dentrodelaimplementacin

Autoreferencias

Programacinorientadaa
objetosenJava

Aplicacionesorientadasaobjetos
Enunaaplicacinorientadaaobjetosdebeexistiruna
clasequerepresentelapropiaaplicacin.Esteserael
puntodondecomenzaralaejecucindelamisma
EnlenguajesnototalmenteorientadoscomoC++enla
funcinmainsecreaunainstanciadeestaclaseyse
llamaaalgunaoperacincomoejecutarparaarrancar
laaplicacin.Sinembargoestonoesobligatorio,yun
malprogramadorpuederealizarunaaplicacinhbrida,
concdigonoorientadoaobjetos

Aplicaciones
orientadasaobjetos

Programacinorientadaa
objetosenJava

EnunlenguajeorientadoaobjetospurocomoJava
estaclasedeaplicacinesobligatoria.
LamquinavirtualJavaseencargadeinstanciaresta
claseyllamaraunaoperacinespecialconnombre
main.Laexistenciadeestaoperacinespecialeslo
quecaracterizaalaclasedeaplicacin

Laclasedeaplicacindebeserpblicaynotenerningnconstructoroun
constructorpordefecto
Almenosdebeimplementarlaoperacinmain,conlasiguientedeclaracin:public
staticmain(String[]args)
publicclassBancoApp{
publicstaticvoidmain(String[]args){
Cuentac1=newCuenta(18400200,PedroJimnez,0.1f);
c1.ingreso(1000);
System.out.println(Ingresorealizado);
}
}
Aplicaciones
orientadasaobjetos

Programacinorientadaa
objetosenJava

Alahoradeejecutarlaaplicacin,deberindicarse
estaclasealamquinavirtualJava

Trascompilarlosficherosdelaltimaversindenuestroejemplo:Cliente.java,
Cuenta.javayBancoApp.javaobtendremoslosficherosenbytecode:
Cliente.class,Cuenta.class,Movimiento.classyBancoApp.class
Finalmente,pasandolaclaseBancoApp.classalamquinavirtualjavapondremos
enfuncionamientolaaplicacin

Lamquinavirtualjava
producirunerrorsise
lepasaunaclasesin
laoperacinmain

$ls
BancoApp.javaCliente.javaCuenta.java
$javac*.java
$ls
BancoApp.classCliente.classCuenta.classMovimiento.class
BancoApp.javaCliente.javaCuenta.java
$javaCuenta
Exceptioninthreadmainjava.lang.NoSuchMethodError:main
$javaBancoApp
Transferenciarealizada
$

Nota:LasclasesqueconstituyenunaaplicacinJavatambinpuedendistribuirsedemaneramuchomscompacta
enunnicoficheroJAR.Conslteselabibliografaparavercomocreanyutilizanestosficheros

Aplicaciones
orientadasaobjetos

Programacinorientadaa
objetosenJava

Herencia
LaherenciaesunmecanismodelaOOPquepermite
construirunaclaseincorporandodemaneraimplcita
todaslascaractersticasdeunaclasepreviamente
existente.Lasrazonesquejustificansunecesidadson
variadas:

Modeladodelarealidad.Sonfrecuenteslasrelacionesde
especializacin/generalizacinentrelasentidadesdelmundoreal,portantoes
lgicoquedispongamosdeunmecanismosimilarentrelasclasesdeobjetos
Evitarredundancias.Todalafuncionalidadqueaportaunaclasedeobjetoses
adoptadademanerainmediataporlaclasequehereda,portantoevitamosla
repeticindecdigoentreclasessemejantes
Facilitarlareutilizacin.Unaclasenotieneporqulimitarsearecibirunaseriede
caractersticasdeotraclaseporherenciadeformapasiva.Tambindisponende
ciertomargendeadaptacindeestascaractersticas
Soportealpolimorfismo
Herencia

Programacinorientadaa
objetosenJava

SeaunaclaseA.SiunasegundaclaseBheredadeA
entoncesdecimos:

AesunascendienteosuperclasedeB.SilaherenciaentreAyBesdirecta
decimosademsqueAeslaclasepadredeB
BesundescendienteosubclasedeA.SilaherenciaentreAyBesdirecta
decimosademsqueBesunaclasehijadeA
A

EnJava,Eiffel,Smalltalkyotroslenguajesorientados
aobjetospuros,todaslasclasesheredan
automticamentedeunasuperclaseuniversal.EnJava
estasuperclasesedenominaObject

Herencia

Programacinorientadaa
objetosenJava

Existendiferentessituacionesenlasquepuede
aplicarseherencia:

Especializacin.DadounconceptoByotroconceptoAquerepresentauna
especializacindeA,entoncespuedeestablecerseunarelacindeherenciaentre
lasclasesdeobjetosquerepresentanaAyB.Enestassituaciones,elenunciado
AesunBsueleseraplicable
Vehculo

Empleado

Figura

Coche

Contable

Cuadrado

Extensin.Unaclasepuedeservirparaextenderlafuncionalidaddeuna
superclasesinquerepresentenecesariamenteunconceptomsespecfico
Lista
Cuenta
Movimiento
ListaSalvable
CuentaConHistorico
recuperar()
salvar()

registra
*

fecha:Date
tipo:Char
importe:Real
saldo:Real

Herencia

Programacinorientadaa
objetosenJava

Especificacin.Unasuperclasepuedeservirparaespecificarlafuncionalidad
mnimacomndeunconjuntodedescendientes.Existenmecanismosparaobligar
alaimplementacindeunaseriedeoperacionesenestosdescendientes
ObjetoGrfico
seleccionar()
mover()
escalar()
cambiarColor()
pintar()

Texto

Lnea

Cuadrado

Construccin.Unaclasepuedeconstruirseapartirdeotra,simplementeporquela
hijapuedeaprovecharinternamenteparteotodalafuncionalidaddelpadre,
aunquerepresentenentidadessinconexinalguna
Lista

Pila

Herencia

Programacinorientadaa
objetosenJava

Ejemplosdeherencia:

Distintostiposdecuentasbancarias

Cuenta
numero:Long
titular:String
saldo:Float
interes:Float
ingreso()
ingresoInteresMes()
leerSaldo()
transferirHasta()

CuentaCorriente

CuentaAhorroPFijo

PlanPensiones

vencimiento:Date

vencimiento:Date
cotizacion:Float
numCuentaOrigen:String

reintegro()
ingresoMes()

Herencia

Programacinorientadaa
objetosenJava

Elementosdeunainterfazdeusuario

Figura
x,y:Integer
mover(nx:Integer,ny:Integer)

Rectngulo
ancho,alto:Integer
escalar(nx:Integer,ny:Integer

Ventana
titulo:String
pintar()

Editor

Boton

pintar()

accion()

Herencia

Programacinorientadaa
objetosenJava

Estructurasdedatos

Contenedor
nelem:Integer
vaciar()
copiar(c:Contenedor)
tamaa():Integer
vacio():Boolean

Secuencia

ContenedorAsociativo

escribir(e:Elemento,pos:Integer)
leer(pos:Integer):Elemento
borrar(pos:Integer)

escribir(e:Elemento,c:Clave)
leer(c:Clave):Elemento
borrar(c:Clave)

Vector

Lista

TablaHash

buffer[nelem]:Elemento

cabecera:Nodo

tabla[nelem]:Elemento

redimensionar(t:Integer)

insertar(e:Elemento,pos:Integer)
insertaPrin(e:Elemento)
insertarFinal(e:Elemento)

funcionHash(c:Clave):Integer

Herencia

Programacinorientadaa
objetosenJava

VamosaestudiarlaimplementacindelaherenciaenJavamedianteelejemplode
unconjuntodetareasprogramables:TPReloj(actualizarunrelojdigitalcada
segundo),TPAviso(mostrarunavisoperidicamente)yTPEjecucion(ejecucindeun
comandocadaciertotiempo)
TareaPeriodica
periodoSegs:Integer
ultimaej:Date
activa:Boolean
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

TPReloj

TPAviso

TPEjecucion

msg:String

cmd:String

+leerMsg():String

+leerCmd():String

+leerHora():String

Herencia

Programacinorientadaa
objetosenJava

LaclaseTareaPeriodicatienelascaractersticascomunesalostrestiposdetarea:
periododeejecucinensegundos,horadelaltimaejecucinybanderadeestado
activo/inactivo
importjava.util.*;
publicclassTareaPeriodica{
intperiodoSegs;//Periododeejecucin
DateultimaEj;//Horadeltimaejecucin
booleanactiva;

publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
//Constructorparaejecucionescadasegundo
publicTareaPeriodica(){
this(1);
}
//Establecerlaltimaejecucinalahoraactual
publicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}

Herencia

Programacinorientadaa
objetosenJava

LaoperacinejecutarTarearealmentenotieneunaimplementacinconcretaaeste
nivel

publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;

//Calcularlahoradelaprximaejecucin
CalendarcalProximaEj=newGregorianCalendar();
calProximaEj.setTime(ultimaEj);
calProximaEj.add(Calendar.SECOND,periodoSegs);

CalendarcalAhora=newGregorianCalendar();

//Comprobarsihapasadoalahoraactual
return(calProximaEj.before(calAhora));
}

publicvoidejecutarTarea(){
System.out.println("Ejecuciondetarea");
}

publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activa=false;}
}

Herencia

Programacinorientadaa
objetosenJava

Paraqueunaclaseherededeotra,utilizaremosel
indicadorextendsenladeclaracindelaclase

importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{

publicTPReloj(){
periodoSegs=60;//Comprobarcadaminuto
actualizarReloj();
activa=true;
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE);
}
}

Atencin!:Aunqueelcdigodeestasclasescompilaperfectamente,laimplementacindelos
constructoresesformalmenteincorrecta.Msadelanteveremosporqu.

Herencia

publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

publicTPAviso(StringaMsg,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
msg=aMsg;
}

Programacinorientadaa
objetosenJava

publicStringleerMsg(){returnmsg;}
}

importjava.lang.Runtime;
importjava.io.IOException;
publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}
Atencin!:Aunqueelcdigodeestasclasescompilaperfectamente,laimplementacindelos
constructoresesformalmenteincorrecta.Msadelanteveremosporqu.

Herencia

Programacinorientadaa
objetosenJava

TodoslasclasesenJavaheredanenltimainstancia
deObject.Inclusosicreamosunaclaseindependiente,
JavalahaceheredarimplcitamentedeObject

Object

#clone():Object
+equals(Objectobj):Boolean
#finalize()
+getClass():Class
+hasCode():int
+notify()
+notifyAll()
+toString():String
+wait()
+wait(timeout:Long)
+wait(timeout:Long,nanos:Integer)

Estohacequelasclasesformenunajerarquacon
Objectcomoraz

Object

...

...

...

...

...

Herencia

Programacinorientadaa
objetosenJava

Enlaimplementacindeunaoperacindelasubclase
noexistediferenciaaparenteentreunatributou
operacinpropiadelaclaseyunatributouoperacin
heredados

Ahorapodemoscrearyusarobjetosdecualquieradelasclasesanteriores.Desdeel
exteriortampocoexistendiferenciasaparentesentrelallamadaaunaoperacin
heredadaopropiadelaclase:
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
TPAvisotpa=newTPAviso(EstudiarProgramacinAvanzada!,60);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
while(!tpa.necesitaEjecucion())
System.println(Esperandoejecucindeaviso...);
System.println(Aviso:+tpa.leerMsg());
}
}
Herencia

Programacinorientadaa
objetosenJava

Lainicializacindelosatributosdeunasuperclaseen
elconstructordeunasubclasepresentavarios
inconvenientesserios:

Resultaredundante.Lasuperclasetieneyaunconstructorquehaceesetrabajo.
Porqurepetircdigoentonces?
Silaclasetieneunalargalistadeascendientes,entonceselconstructorseramuy
largo
Lasuperclasepuedetenerunainicializacincompleja,ylainclusindelcdigode
inicializacinenlasubclasepuederequerirunconocimientoexcesivodela
superclaseporpartedelimplementador
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

publicTPAviso(StringaMsg,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
}
Herencia

Programacinorientadaa
objetosenJava

Elprocedimientocorrectoconsisteenrealizaruna
llamadaalconstructordelasuperclaseparaquerealice
lainicializacindelosatributosheredados
EnJavaestallamadaalconstructordelasuperclase
serealizaconlaoperacionsuper()seguidadelos
parmetrosdeinicializacindealgunodelos
constructoresdelpadredelaclase

LaimplementacincorrectadelconstructordelaclaseTPAvisoseraportantola
siguiente:
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
}
Herencia

Programacinorientadaa
objetosenJava

Ydelasotrasdossubclases:
importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{

publicTPReloj(){
super(60);
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"
+cal.get(Calendar.MINUTE);
}
}
importjava.lang.Runtime;
importjava.io.IOException;
publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}

Herencia

Programacinorientadaa
objetosenJava

nicamentedebellamarseexplcitamenteaun
constructordelascendienteinmediato
Elconstructordeesteltimorealizarasuvezuna
llamadaaunconstructordesuascendienteinmediatoy
assucesivamentehastainicializartodoslosatributos
heredados

A
super(...)

super(...)
B
super(...)

super(...)
C

Herencia

Programacinorientadaa
objetosenJava

Paraterminar,esposibleimpedirlaherenciaapartir
deunaclasedeclarndolacomofinal
Sinembargo,estaesunacaractersticaquedebeser
utilizadaconprudencia,yaquepuederestringiren
excesolaextensinyreutilizacindelasclasesdel
sistemaenelfuturo

importjava.lang.Runtime;
importjava.io.IOException;
finalpublicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}
Herencia

Programacinorientadaa
objetosenJava

Adicin,redefinicinyanulacin
Laherenciaensnoserataninteresantesinofuera
porlaposibilidaddeadaptareneldescendientelos
miembrosheredados

Adicin.Trivialmenteeldescendientepuedeaadirnuevosatributosyoperaciones
quesesumanalosrecibidosatravsdelaherencia
Redefinicin.Esposibleredefinirlaimplementacindeunaoperacinheredada
paraadaptarlaalascaractersticasdelaclasedescendiente.Tambinesposible
cambiareltipodeunatributoheredado
Anulacin.Cuandounatributouoperacinheredadosnotienenutilidadenel
descendientes,puedenseranuladosparaimpedirsuutilizacin

Notodosloslenguajesorientadosaobjetossoportan
estascaractersticas,enespeciallaanulacin

Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

LaredefinicinserealizaenJavaylamayoradelos
lenguajesOOdefiniendonuevamentelaoperacin(con
losmismosargumentos)eneldescendiente

LasclasesdescendientesTPReloj,TPEjecucionyTPAvisonoestnoperativas
todavaporquelaimplementacindeejecutarTarea()quecontieneneslaheredadade
TareaPeriodica,quenohacenadaenparticular
Esprecisoredefinirestaoperacinencadaunadelassubclasesparaquerealicen
lastareascorrespondientes
TareaPeriodica
periodoSegs:Integer
ultimaej:Date
activa:Boolean
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

TPReloj

+leerHora():String
+ejecutarTarea()

TPAviso

TPEjecucion

msg:String

cmd:String

+leerMsg():String
+ejecutarTarea()

+leerCmd():String
+ejecutarTarea()

Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{

publicTPReloj(){
super(60);
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE);
}

publicvoidejecutarTarea(){
Calendarcal=newGregorianCalendar();
intmin=cal.get(Calendar.MINUTE);

if(min==0||min==30)
System.out.println("Hora:"+cal.get(Calendar.HOUR_OF_DAY)
+""+min);
}
}

Adicin,redefinicin
yanulacin

importjava.lang.Runtime;
importjava.io.IOException;

Programacinorientadaa
objetosenJava

publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
publicvoidejecutarTarea(){
try{
Runtime.getRuntime().exec(cmd);
}
catch(IOExceptione){
System.out.println("Imposibleejecutarcomando:"
+cmd);
}
}
}
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
publicvoidejecutarTarea(){
System.out.println("ATENCINAVISO:"+msg);
desactivar();
}
}

Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

Cadatareaejecutaahorasufuncin,aunquelallamadaesaparentementelamisma
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
TPAvisotpa=newTPAviso(EstudiarProgramacinAvanzada!,60);
TPEjecuciontpe=newTPEjecucion(rm~/tmp/*,3600);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
while(!tpa.necesitaEjecucion())
System.println(Esperandoejecucindeaviso...);
tpa.ejecutarTarea();
while(!tpr.necesitaEjecucion())
System.println(Esperandoejecucindecomando...);
tpe.ejecutarTarea();
}
}

Despusdelaredefinicin,eneldescendientees
posiblellamaralaversinoriginaldelaoperacinenel
ascendientemediante:super.operacionRedefinida()

Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

Otrousoposibledelapalabraclavefinalesimpedirla
redefinicindeunaoperacinenlassubclases

importjava.util.*;
publicclassTareaPeriodica{
intperiodoSegs;
DateultimaEj;
booleanactiva;

publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
publicTareaPeriodica(){this(1);}

finalpublicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}

finalpublicbooleannecesitaEjecucion(){
//Implementacindelaoperacin
}
publicvoidejecutarTarea(){
System.out.println("Ejecuciondetarea");
}

finalpublicvoidactivar(){activa=true;}
finalpublicvoiddesactivar(){activa=false;}
}

Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

Laanulacinesunmecanismomenostil,ycon
menorsoporteporpartedeloslenguajesde
programacin
EnJavaesposibleimpedirelaccesoaunatributo
redeclarndoloenunasubclasecomoprivadoo
protegido,segnseaelniveldeproteccinquese
desee

publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

//Impedirelaccesodesdeelexteriorylassubclases
//alatributoactiva
privatebooleanactiva;
publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
//Restodelaimplementacindelaclaseapartirdeaqu
Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

Sinembargo,Javanopermiteredefinirunaoperacin
haciendosuniveldeaccesomsrestrictivo
Unasolucinparcialconsistiraenredefinirlacomo
vacaoincluyendouncdigoqueimpidasuutilizacin

publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicvoidactivar(){}
publicvoiddesactivar(){
System.out.printl(Error:llamadaaoperacinprivada);
System.getRuntime().exit(1);
}
publicStringleerMsg(){returnmsg;}
publicvoidejecutarTarea(){
System.out.println("ATENCINAVISO:"+msg);
desactivar();
}
}
Adicin,redefinicin
yanulacin

Programacinorientadaa
objetosenJava

Proteccinyherencia
Hemosvistoanteriormentecomolosdistintosniveles
deproteccinlimitanelaccesoalosmiembrosdela
clasedesdeelexterior.Perocomoafectanestos
nivelesdeproteccinalosmiembrosheredados?

Miembrospblicos.Sonaccesiblesdesdelosdescendientes,yseheredancomo
pblicos
Miembrosprivados.Nosonaccesiblesdesdelosdescendientes
Miembrosconaccesoaniveldepaquete.Sonaccesiblesdesdelosdescendientes
siempreycuandopertenezcanalmismopaquetequeelascendiente.Seheredan
conelmismoniveldeproteccin

Unnuevoniveldeproteccineseldemiembros
protegidos(protected).Unmiembroprotegidoes
accesiblenicamentedesdelosdescendientes

Proteccinyherencia

Programacinorientadaa
objetosenJava

Adems,unmiembroprotegidomantieneenlas
subclaseselniveldeaccesoprotegido

Ennuestroejemplo,losatributosdelaclaseTareaPeriodicasonaccesiblesdesde
TPReloj,TPEjecucionyTPAvisoporquealperteneceralmismopaquetesonamigas
ParapermitirelaccesoalosatributosdelaclaseTareaPeriodicanicamente
desdelosdescendientesesconvenientemarcarloscomoprotegidos
importjava.util.*;
publicclassTareaPeriodica{
protectedintperiodoSegs;
protectedDateultimaEj;
booleanactiva;

publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
//Restodeoperacionesdelaclaseapartirdeaqu

Proteccinyherencia

Programacinorientadaa
objetosenJava

Clasesabstractas
Existenclasesquerepresentanconceptostan
genricosquenotienesentidosuinstanciacinen
objetos
Ademsenestetipodeclasespuedeserimposibleo
intillaimplementacindeciertasoperaciones
Lautilidaddeestetipodeclasesestenlaaplicacin
deherenciaparaobtenerclasesquerepresentan
conceptosconcretosparalosquesquetienesentido
suinstanciacin

LaclaseTareaPeriodicaesunclaroejemplo:porssolanotieneutilidad,pero
simplificamucholaconstruccindelasotrastresclases.Dehecho,laoperacin
ejecutarTarea()enTareaPeriodicanotieneunaimplementacintil
Clasesabstractas

Programacinorientadaa
objetosenJava

Estasclasessedenominanclasesabstractasyeste
tipodeoperacionessinimplementacinposible,
operacionesabstractas
Lasoperacionesabstractasdebenserimplementadas
obligatoriamenteenalgunadelassubclasesparaque
laclasecorrespondienteseainstanciable
Unaclaseabstractapuedenotenerningunaoperacin
abstracta,perounaclasequecontengaalmenosuna
operacinabstractadebeserdeclaradacomoabstracta
EnJava,utilizandoladeclaracinabstractpodremos
establecerunaclaseounaoperacincomoabstracta

Clasesabstractas

Programacinorientadaa
objetosenJava

VamosadeclararlaclaseTareaPeriodicaysuoperacinejecutarTarea()como
abstractas
importjava.util.*;

abstractclassTareaPeriodica{
intperiodoSegs;
DateultimaEj;
booleanactiva;

publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
publicTareaPeriodica(){this(1);}

publicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}

publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;

//Restodelaimplementacindeesta
//operacinaqu
}
abstractpublicvoidejecutarTarea();
publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activa=false;}
}
Clasesabstractas

Programacinorientadaa
objetosenJava

Javadevuelveahoraunerrorentiempodecompilacinsiseintentacrearunobjeto
delaclaseTareaPeriodica
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
}
}
AppGestorTareas.java:XX:classTareaPeriodicaisanabstractclass;cannotbeinstantiated
TareaPeriodicatp=newTareaPeriodica();
^
1error

Laabstraccindeunaclasesepropagaporla
jerarquadeherenciahastaquetodaslasoperaciones
quedanimplementadas

Clasesabstractas

Programacinorientadaa
objetosenJava

Laideadeclaseabstracta,llevadaalextremo,nos
llevaenJavaalasinterfaces.Unainterfazessimilara
unaclasetotalmenteabstracta:

Todaslasoperacionesdelainterfazsonimplcitamenteabstractas,esdecir,
carecendeimplementacin
Unainterfaznopuedeconteneratributos

Lasinterfacessirvenparaespecificarlasoperaciones
queobligatoriamentedebenimplementarunaseriede
clases
Laimplementacindeunainterfaznoserealiza
medianteherencia(extends)sinomedianteimplements.
Noobstante,elcomportamientoessimilaraldela
herencia,aunquemssencillo

Clasesabstractas

Programacinorientadaa
objetosenJava

Laideadeclaseimplementaunainterfaz,esta
implementacindebesercompleta,esdecir,detodas
lasoperacionesdelainterfaz

PodemostransformarTareaPeriodicaenunainterfaz,deformaqueespecifiquelo
quetienequeimplementarcualquierclasequerepresenteunatareaperidica.Este
enfoqueproporcionamayorlibertadalahoradedisearlasotrasclases
<<interfaz>>
TareaPeriodica

+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

TPReloj

+leerHora():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

TPEjecucion

TPAviso

cmd:String

msg:String

+leerCmd():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

+leerMsg():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()

Clasesabstractas

Programacinorientadaa
objetosenJava

LainterfazTareaPeriodicaylaclaseTPRelojtendranahoraelsiguienteaspecto.
Lasotrasclasestendranimplementacionessimilares
publicinterfaceTareaPeriodica{

booleannecesitaEjecucion();
voidejecutarTarea();
voidactivar();
voiddesactivar();
}

importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojimplementsTareaPeriodica{
DateultEjecucion;
booleanactiva;

publicTPReloj(){activa=true;ultEjecucion=newDate()}

publicvoidejecutarTarea(){
Calendarcal=newGregorianCalendar();
intmin=cal.get(Calendar.MINUTE);
System.out.println("Hora:"+cal.get(Calendar.HOUR_OF_DAY)
+""+min);
ultEjecucion=cal.getTime();
}

Clasesabstractas

Programacinorientadaa
objetosenJava

publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;
CalendarcalProximaEj=newGregorianCalendar();
CalendarcalUltEjecucion=newGregorianCalendar();
calUltEjecucion.setTime(ultEjecucion);
CalendarcalAhora=newGregorianCalendar();
if(calAhora.equal(calUltEjecucion))
returnfalse;
intmin=calAhora.get(Calendar.MINUTE);
if(min==00||min==30)
returntrue;
returnfalse;
}
publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activar=false;}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+
cal.get(Calendar.MINUTE);
}
}
Clasesabstractas

Programacinorientadaa
objetosenJava

Unaclasepuedeimplementarmsdeunainterfaz
Unainterfazpuedeheredardeotrainterfaz
Cuandoutilizarunainterfazenlugardeunaclase
abstracta?

Porsusencillezserecomiendautilizarinterfacessiemprequeseaposible
Silaclasedebeincorporaratributos,oresultainteresantelaimplementacinde
algunadesusoperaciones,entoncesdeclararlacomoabstracta

EnlabibliotecadeclasesdeJavasehaceunuso
intensivodelasinterfacesparacaracterizarlasclases.
Algunosejemplos:

Paraqueunobjetopuedaserguardadoenunficherolaclasedebeimplementarla
interfazSerializable
Paraqueunobjetoseaduplicable,suclasedebeimplementarCloneable
Paraqueunobjetoseaordenable,suclasedebeimplementarComparable

Clasesabstractas

Programacinorientadaa
objetosenJava

Herenciamltiple
Consisteenlaposibilidaddequeunaclasetenga
variosascendientesdirectos
Puedesurgirdemanerarelativamentefrecuentey
naturalduranteeldiseo

FiguraGeometrica

Lista

almacena
*

Punto

Poligono

FicheroLectura

FicheroEscritura

FicheroLecturaEscritura

Imagen

EnlaceURL

ImagenSensible

Herenciamltiple

Programacinorientadaa
objetosenJava

Tieneclaramenteaspectospositivos

Surgedemaneranaturalaldescribirlaestructuradeunsistema
Proporcionamuchaflexibilidadalahoradeconstruirclasesnuevas

Perotambinaspectosnegativos

Complicaeldiseo.Lajerarquadeclasesdejadesertaljerarquapara
pasaraserunared
Provocaproblemasdeeficiencia.Lallamadaaunaoperacinheredada
implicalabsquedapormltiplescaminos
Ambigedad:dosatributosuoperacionesconelmismonombrepueden
llegaraunaclasepordoscaminosdistintos
Herenciarepetida:enunaestructuraconformaderombo,unatributou
operacinpuedellegaraunaclasepordoscaminosdistintos
D
A

atributoX

atributoX

atributoX

C
C

Herenciamltiple

Programacinorientadaa
objetosenJava

LaapuestadeloscreadoresdeJavaesclara:no
permitirlaherenciamltiple,porlasrazonesexpuestas
anteriormente
Avecesesposiblesustituirlaherenciamltiplepor
unacombinacinherencia/composicin,aunqueel
resultadonopuedeconsiderarseequivalente

FiguraGeometrica

Poligono

contiene
1

Lista

almacena

Segmento

listaPuntos():Lista

FiguraGeometrica

Poligono

contiene
1

aadir(s:Segmento)

Lista

aadir(s:Segmento)
borrarPrim()
borrarUlt()

almacena
*

Segmento

Herenciamltiple

Programacinorientadaa
objetosenJava

Adems,Javasquepermitelaimplementacinde
unaovariasinterfacesademsdelaherencia,loque
puedeconsiderarseunaformarestringidadeherencia
mltiple
Unaclasepuedeheredardeotraeimplementarunao
variasinterfacessinqueaparezcanlosproblemas
asociadosconlaherenciamltiple

<<interfaz>>
FiguraGeometrica

Lista

almacena
*

Segmento

Poligono

Herenciamltiple

Programacinorientadaa
objetosenJava

Polimorfismo
Sondosmecanismosrelacionadosqueotorganala
OOPunagranpotenciafrenteaotrosparadigmasde
programacin
nicamentetienensentidoporlaexistenciadela
herencia
Elpolimorfismo(oupcasting)consisteenlaposibilidad
dequeunareferenciaaobjetosdeunaclasepueda
conectarsetambinconobjetosdedescendientesde
sta

Ara=newA();//Asignacinordinaria
Brb=ra;//Asignacinpolimorfa

objeto:A

rb:B
ra:A

Brb=newA();//Asignacionpolimorfa
Polimorfismo

Programacinorientadaa
objetosenJava

publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
TareaPeriodicatp;
tp=tpr;
tp.desactivar();
tp=tpa;
tp.desactivar();
tp=tpe;
tp.desactivar();
}
}

Elsentidodelpolimorfismoesrealizarunageneraliza
cin,olvidarlosdetallesconcretosdeunoovarios
objetosdedistintasclasesybuscarunpuntocomna
todosellosenunancestro

Polimorfismo

Programacinorientadaa
objetosenJava

Lamayoradelasveces,lasconexionespolimorfasse
realizandemaneraimplcitaenelpasodeargumentos
aunaoperacin.Deestamaneraesposibleescribir
operacionespolimorfasquerecibanobjetosde
mltiplesclases

publicclassAppGestorTareas{
privatestaticvoidesperarEjecutar(TareaPeriodicatp)
{
while(!tp.necesitaEjecucion());
tp.ejecutarTarea();
}
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
esperarEjecutar(tpr);
esperarEjecutar(tpa);
esperarEjecutar(tpe);
}
}
Polimorfismo

Programacinorientadaa
objetosenJava

Otraaplicacinmuytileslaconstruccinde
estructurasdedatosquepuedanmantenerobjetosde
distintasclases

VamosaimplementarunanuevaclaseGestorTareasquevaacontenerunalistade
tareasarealizar.LallamadaachequearEjecutar()realizarlacomprobaciny
ejecucindelastareasquelorequieran
importjava.lang.Exception;
classDemasiadasTareasextendsException{}
publicclassGestorTareas{
TareaPeriodica[]tareas;
intnTareas,maxTareas;
publicGestorTareas(intaMaxTareas){
nTareas=0;
maxTareas=aMaxTareas;
tareas=newTareaPeriodica[maxTareas];
}
//Sigue...
Polimorfismo

Programacinorientadaa
objetosenJava
//ContinuacindelaclaseGestorTareas
publicvoidnuevaTarea(TareaPeriodicatp)
throwsDemasiadasTareas{
if(nTareas==maxTareas)
thrownewDemasiadasTareas();
tareas[nTareas++]=tp;
}

publicvoidchequearEjecutar()
{
for(intt=0;t<nTareas;t++)
if(tareas[t].necesitaEjecucion())
tareas[t].ejecutarTarea();
}
}
importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
GestorTareasgt=newGestorTareas(10);
try{
gt.nuevaTarea(newTPReloj());
gt.nuevaTarea(newTPAviso(Hapasadounminuto,60));
gt.nuevaTarea(newTPEjecucion(/bin/sync,120));
}catch(DemasiadasTarease){
System.out.println(Mmmm....estonodeberiahaberpasado);
}
gt.chequearEjecutar();
}
}
Polimorfismo

Programacinorientadaa
objetosenJava

Perosiempredebequedarclaroquetraslaconexin
polimorfanicamentepodemosaccederalasopera
cionespertenecientesalaclaseasociadaalarefe
rencia.Elrestodeoperacionesdelobjetonoson
accesiblesatravsdeestareferencia

publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TareaPeriodicatp;
tp=tpr;
tp.desactivar();//Ok
tp.leerHora()//Error!!
tpr.leerHora();//Ok
}
}
AppGestorTareas.java:XX:cannotresolvesymbol
symbol:methodleerHora()
location:classTareaPeriodica
tp.leerHora();
^
1error
Polimorfismo

Programacinorientadaa
objetosenJava

EnJava,unareferenciaaObjectpuedeserconectada
acualquierobjeto,puestoquecomosabemosesun
ancestrodetodaslasclases

publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
Objecto;
o=tpr;
System.out.println(o.getClass().getName());
}
}

Adems,lasinterfacesimplementadasporunaclase
tambinpuedenserutilizadaspararealizarconexiones
polimorfas

Polimorfismo

Programacinorientadaa
objetosenJava

Ligaduradinmica
Entendemosporresolucindeunallamadaelproceso
porelcualsesustituyeunallamadaaunafuncinpor
unsaltoaladireccinquecontieneelcdigodeesta
funcin
Normalmente,laresolucindellamadasserealizaen
entiempodecompilacin,porqueresultamssencilloy
sobretodomseficiente.Cuandolaaplicacinseest
ejecutando,lasllamadasyaestnpreparadas.Este
enfoquesedenominaligaduraesttica

f()

CALL_f
Ligaduradinmica

Programacinorientadaa
objetosenJava

ElproblemaapareceenOOPcuandorealizamosuna
conexinpolimorfayllamamosaunaoperacin
redefinida

f()

f()

f()

Ar=??
r.f()

CALL_A_f?
CALL_B_f?
CALL_C_f?

Elcompiladornotieneinformacinpararesolverla
llamada.Pordefectoutilizaraeltipodelareferencia,y
portantogeneraraunallamadaaA.f()
Perolareferenciarpuedeapuntaraobjetosdelas
clasesA,BoC,condistintasversionesdef()

Ligaduradinmica

Programacinorientadaa
objetosenJava

Lasolucinconsisteenesperararesolverlallamada
altiempodeejecucin,cuandoseconocerealmente
losobjetosconectadosar,yculeslaversindef()
apropiada.Esteenfoquederesolucindellamadasse
denominaligaduradinmicayesmuchomslentay
complejaquelaesttica
Haytresenfoquesposiblesalahoradeescogerentre
ligaduraestticaodinmica:

Establecerlaligaduraestticapordefecto.Elprogramadorpuedeactivarla
ligaduradinmicaparaunafuncinconcretacuandolovenecesario(C++)
Utilizaruncompiladorinteligentequedecidelaligaduraestticaodinmicaen
funcindelempleoquesehacedecadafuncin(Eiffel)
Establecerlaligaduradinmicaparatodaslasfuncionesyevitarproblemasacosta
deeficienciaenlaejecucin(Smalltalk,Java)

Ligaduradinmica

Programacinorientadaa
objetosenJava

Portanto,laligaduradinmica,pordefectoenJava,
garantizasiemprelallamadaalaversincorrectade
cadafuncin,conindependenciadelusodeconexiones
polimorfasono

PortantoenJavalasllamadasalafuncinejecutarTarea()seresuelven
correctamente,apesarderealizarseatravsdeunareferenciaaTareaPeriodica
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
TareaPeriodicatp;
tp=tpr;
tp.ejecutarTarea();//VersindeTPReloj
tp=tpa;
tp.ejecutarTarea();//VersindeTPAviso
tp=tpe;
tp.ejecutarTarea();//VersindeTPEjecucion
}
}

Ligaduradinmica

Programacinorientadaa
objetosenJava

Informacindeclasesentiempodeejecucin
Trasrealizarunaconexinpolimorfaesfrecuentela
necesidaddevolverarecuperarelobjetooriginal,para
accederasusoperacionespropias
Setratadelaoperacininversaalpolimorfismo
(upcasting),denominadadowncasting
Sielpolimorfismoimplicaunageneralizacin,el
downcastingimplicaunaespecializacin
Alcontrarioqueelupcasting,eldowncastingnopuede
realizarsedirectamentemedianteunaconexinconuna
referenciadelaclasedelobjeto

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

TrascrearunobjetodetipoTPRelojyconectarlomedianteunareferenciaa
TareaPeriodica,intentamosrecuperarnuevamenteunareferenciadetipoTPRelojal
objeto.Noesposibledemaneradirecta
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=tp;//downcasting?
}
}
AppGestorTareas.java:XX:incompatibletypes
found:TareaPeriodica
required:TPReloj
TPRelojtr=tp;
^
1error

Unsimplecastingpermiteforzarlaconexinala
referencia

publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=(TPReloj)tp;//downcasting
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Unintentodecastingimposiblegeneraruna
excepcinClassCastExceptionentiempodeejecucin

publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=(TPReloj)tp;//downcastingok
//Downcastingimposible:lanzaexcepcinClassCastException
TPAvisota=(TPAviso)tp;
}
}
ExceptioninThreadmainjava.lang.ClassCastException
atAppGestorTareas.main(AppGestorTareas.java:XX)

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Podemoscapturarestaexcepcinparadeterminarsiel
objetoapuntadoporlareferenciaesdeltipoesperadoo
no,realizandoaccionesdiferentesencadacaso

importjava.lang.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;
TPRelojtr;

//Posiblementeenalgnpuntolareferenciatphasidoconectada
//conunobjetodelaclaseTPReloj
...
try{
tr=(TPReloj)tp;
System.out.println(Lahoraactuales:+tr.leerHora());
}
catch(ClassCastExceptione){
System.out.println(Lareferenciatpnoapuntaaunobjeto
+delaclaseTPReloj);
}
}
}
Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava
importjava.lang.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte;

//tpesconectadaaalgnobjeto
...
try{
tr=(TPReloj)tp;
//Operarcontr
return;
}
catch(ClassCastExceptione){
//SinoesdetipoTPReloj,continuamosporaqu
}
try{
ta=(TPAviso)tp;
//Operarconta
return;
}
catch(ClassCastExceptione){
//SinoesdetipoTPAviso,continuamosporaqu
}
try{
te=(TPEjecucion)tp;
//Operarconte
return;
}
catch(ClassCastExceptione){
//SitampocoesdetipoTPEjecucinEntoncesdequetipoes?
System.out.println(Error:objetodeclasedesconocida);
}
}
}
Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Muchomscmodoesutilizarinstanceofpara
determinasielobjetoesdelaclaseesperadaantesde
realizarelcasting

importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte;

//tpesconectadaaalgnobjeto
...
if(tpinstanceofTPReloj){
tr=(TPReloj)tp;
//Operarcontr
}
else
if(tpinstanceofTPAviso){
ta=(TPAviso)tp;
//Operarconta
}
else
if(tpinstanceofTPEjecucion){
te=(TPEjecucion)tp;
//Operarconte
}
else
System.out.println(Error:objetodeclasedesconocida);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

LaoperacingetClass()deObjectdevuelveunobjeto
delaclaseClassquepermiteobtenerentiempode
ejecucingrancantidaddeinformacindelaclaseala
queperteneceelobjeto.Elatributoestticoclassdela
clasetambindevuelveunareferenciaaesteobjeto

importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;

//tpesconectadaaalgnobjeto
...
Classc=tp.getClass();
System.out.println(Lareferenciatpapuntaaunobjetodelaclase:
+c.getName());
Classc=TareaPeriodica.class;
if(c.isInterface())
System.out.println(TareaPeriodicaesunaInterfaz);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

LaslibrerasdecontenedoresdeJava(java.util)
utilizanelpolimorfismoparaconseguirgenericidad,
trabajandosiempreconObject
Alahoraderecuperarlosobjetosalmacenados,es
necesarioutilizardowncastingparaconectarconuna
referenciadelaclaseapropiada

importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedListl=newLinkedList;
//Aadirelementos
l.add(newString(Jan));
l.add(Granada);
//Recuperarelprimerelemento
Strings=(String)l.get(0);
System.out.println(s);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Apartirdelaversin5,Javahaincorporadosimilaral
utilizadoporlostemplatesdeC++paraespecificarel
tipodeloselementosdelcontenedor
Laventajaesquelareferenciadevueltaes
directamentedeltipoespecificadoenlacreacindel
contenedor

importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedList<String>l=newLinkedList<String>;
//Aadirelementos
l.add(newString(Jan));
l.add(Granada);
//Yanoesnecesarioeldowncasting
Strings=l.get(0);
System.out.println(s);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Otroinconvenientedelusodelpolimorfismoparala
implementacindeloscontenedoresesquelostipos
simples(int,char,etc.)nopuedenalmacenarse
directamente,alnoserclasesdeobjetos
Parasolucionarlo,Javaincorporaunaclasewrapper
paracadatiposimple:(int>Integer,char>Character,
etc.)

importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedListl=newLinkedList;
//Aadirelementos
l.add(newInteger(5));
l.add(newInteger(3));
//Recuperarelprimerelemento
inti=((Integer)l.get(0)).intValue();
System.out.println(i);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

Nuevamente,apartirdelaversin5,esteproblemase
haeliminadoconelautoboxingdetipossimples
Esdecir,Javatransformauntiposimpleensuclase
wrappercuandoesnecesariodemaneraautomtica
EsalgosimilaralaconstruccinautomticadeString
apartirdearraysdecaractresqueyaconocemos

importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedList<Integer>l=newLinkedList<Integer>;
//Aadirelementos.LaconversinaIntegeres
//automtica
l.add(5);
l.add(3);
//Recuperarelprimerelemento.Laconversina
//intesautomtica
inti=l.get(0);
System.out.println(i);
}
}

Informacinde
clasesentiempode
ejecucin

Programacinorientadaa
objetosenJava

OtrostemasdeintersenJava
Entrada/Salida.LalibreradeclasesdeJavadispone
degrancantidaddeclasesparalagestintransparente
deE/S.Estasclasespuedencombinarseparacrear
flujosdedatosespecializados
E/SBinaria(streams):

LasclasesFileInputStreamyFileOutputStreampermiteabrirstreamsdeE/S
secuencialaficherosendisco.LaclaseRandomAccessFilepermiteleeryescribir
informacinaunficherodeformaaleatoria
LasclaseBufferedInputStreamyBufferedOutputStreampermiteleeryescribir
informacindeuninput/outputstream,utilizandounbufferintermedioparaacelerar
lasoperaciones
LasclasesDataInputStreamyDataOutputStreampermiteleeryescribirtipos
simplesenuninput/outputstream

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Ejemplo.Lecturayescriturabsicasenunfichero:
importjava.io.*;
publicclassESBinaria{
publicstaticvoidmain(String[]args){
DataOutputStreamds=
newDataOutputStream(
newBufferedOutputStream(
newFileOutputStream(datos)));
ds.writeInt(2);
ds.writeFloat(4.5);
ds.writeChars(Hola);
ds.close();
ds=newDataInputStream(
newBufferedInputStream(
newFileInputStream(datos)));
intk=ds.readInt();
System.out.println(k);
ds.close();
}
}

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

E/Sdecaracteres(readers)

LasclasesFileReaderyFileWriterpermiteabrirreaders/writersdeacceso
secuencialaficherosendisco
LasclasesBufferedReaderyBufferedWriterpermiteleeryescribirinformacin
utilizandounbufferintermedioparaacelerarlasoperaciones.Posibilitanel
leer/escribirlineascompletas
LasclasesInputStreamReaderyOutputStreamWriterpermitenconvertirunstream
enunreader/writer
LaclaseespecializadaPrintWriterpermiteescribirdirectamentecualquiertipode
datoenunwriter.SuusoesmscmodoqueeldeunBufferedWriter
LaclaseespecializadaScannerpermiteleerdemanerasencillacualquiertipo
simpledeunficherodetexto.Suusoesmscomodoquemediante
BufferedReader

VerelapartadoI/O:ReadingandWritingdeltutorial
Javaylaspginasdelasclasescitadasenelmanual
dereferenciaparamsinformacin

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Ejemplo.EscrituradeunficheromedianteBufferedWriteryPrintWriter:
importjava.io.*;
publicclassESTexto{
publicstaticvoidmain(String[]args){
try{
BufferedWriterbw=newBufferedWriter(newFileWriter(datos.txt));
bw.write(Hola);
bw.writeLine();
bw.write(newInteger(3).toString());
bw.writeLine();
bw.write(newFloat(10.3).toString());
bw.close();
PrintWriterpw=newPrintWriter(datos.txt);
pw.println(Hola);
pw.println(3);
pw.println(10.3);
pw.close();
}
catch(IOExceptione){
System.out.println(ErrordeE/S);
}
}
}

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Haydosmtodosdelectura:

Elprimerousalaoperacinparse()delasclaseswrapperdelostiposbsicos
Elsegundo,msflexibleysencillo,utilizalaclaseScanner

importjava.io.*;
importjava.util.Scanner;
publicclassESTexto{
publicstaticvoidmain(String[]args){
try{
BufferedReaderbr=newBufferedReader(
newFileReader(datos.txt));
Strings=br.readLine();
intk=Integer.parseInt(br.readLine());
floatp=Float.parseFloat(br.readLine());
br.close();
Scannersc=newScanner(newFile(datos.txt));
s=sc.nextLine();
k=sc.nextInt();
p=sc.nextFloat();
sc.close();
}
catch(IOExceptione){
System.out.println(ErrordeE/S);
}
}
}

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Serializacin.Unadelascaractersticasmspotentes
deJavaeslaposibilidaddeserializarunobjeto,es
decir,convertirloenunasecuenciadebytesyenviarlo
aunficheroendisco,porunsocketaotroordenadora
travsdelared,etc.Elprocesoseraelsiguiente:

DeclararlaimplementacindelainterfazSerializableenlaclasequedeseemos
serializar.Setratadeunainterfazvaca,porloquenohayoperacionesque
implementar
ParaserializarelobjetocrearamosunstreamObjectOutputStreamyescribiramos
elobjetomediantelaoperacinwriteObject()
ParadeserializarelobjetocrearamosunstreamObjectInputStream,leeramosel
objetomediantereadObject()yrealizaramosuncastingalaclasedelobjeto

VerelapartadoObjectSerializationdeltutorialJava
paramsinformacin

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

VamosamodificarahoraelconstructordelaclaseCuentaylaoperacinsalvar()
paraqueseancapacesdecargarysalvarelhistoricodemovimientos.Lacapacidad
deserializacindeJavapermitesalvarlalistaenlazadadeungolpe
importjava.io.*;
importjava.util.*;
//EsnecesarioquetantolasclasesClientecomoMovimientoimplementenlainterfaz
//Serializableparaquelosobjetospuedanserescritosendisco
classMovimientoimplementsSerializable{
Datefecha;
chartipo;
floatimporte;
floatsaldo;

publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldo=aSaldo;
}
}
publicclassCuenta{
longnumero;
Clientetitular;
privatefloatsaldo;
floatinteresAnual;

LinkedListmovimientos;
Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;

movimientos=newLinkedList();
}

Cuenta(longaNumero)throwsFileNotFoundException,
IOException,ClassNotFoundException{
ObjectInputStreamois=newObjectInputStream(newFileInputStream(aNumero+".cnt"));
numero=ois.readLong();
titular=(Cliente)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
movimientos=(LinkedList)ois.readObject();
ois.close();
}

voidsalvar()throwsFileNotFoundException,IOException{
ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream(numero+".cnt"));
oos.writeLong(numero);
oos.writeObject(titular);
oos.writeFloat(saldo);
oos.writeFloat(interesAnual);
oos.writeObject(movimientos);
oos.close();
}

//RestodeoperacionesdelaclaseCuentaapartirdeaqu

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Multitarea.Esposibleimplementarunaovariastareas
queseejecutenenvariashebrasdeejecucinen
paralelo,delasiguientemanera

ConstruirunaclasequerepresentelatareayherededelaclaseJavaThread
Redefiniendolaoperacinrun()deThreadpodremosintroducirelcdigoque
deseamosejecutarenlahebra
Paraarrancarlanuevahebrabastaconcrearunobjetodelaclaseyejecutarla
operacinstart()
Sisedeseapararlahebraduranteuntiempodeterminado,puedeutilizarsela
operacinsleep(intsegs)
Latareafinalizacuandoseelhilodeejecucinllegadeformanaturalalfinaldela
operacinrun()

VerelapartadoThreads:doingtwoormoretasksat
oncedelTutorialJavaparamsinformacin

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Ejemplo:ungestordetareasquefuncionaenparaleloconelrestodelaaplicacin,
realizandolacomprobacinperidicadelastareasquerequierenejecucin
importjava.lang.Exception;
classDemasiadasTareasextendsException{}
publicclassGestorTareasextendsThread{
TareaPeriodica[]tareas;
intnTareas,maxTareas;
booleanterminar;
publicGestorTareas(intaMaxTareas){
super("GestorTareas");

terminar=false;
nTareas=0;
maxTareas=aMaxTareas;
tareas=newTareaPeriodica[maxTareas];
}
publicvoidnuevaTarea(TareaPeriodicatp)throwsDemasiadasTareas{
if(nTareas==maxTareas)
thrownewDemasiadasTareas();
tareas[nTareas++]=tp;
}

//Sigue...
Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Laoperacinterminar()vaapermitirforzarlafinalizacindelgestordetareas
//ContinualaclaseGestorTareas

publicvoidrun()
{
System.out.println("Gestordetareasenfuncionamiento");

while(!terminar){
for(intt=0;t<nTareas;t++)
if(tareas[t].necesitaEjecucion())
tareas[t].ejecutarTarea();

//Esperarunsegundoantesdevolveracomprobar
try{
sleep(1);
}
catch(InterruptedExceptione){};
}
System.out.println("Finalizandogestordetareas");
}

voidterminar(){terminar=true;}
}

Otrostemasde
intersenJava

Programacinorientadaa
objetosenJava

Estaaplicacincontaracondoshilosdeejecucinenparalelo,unoprincipalyotro
asociadoalgestordetareas
publicclassAppGestorTareas{
publicAppGestorTareas(){}

publicstaticvoidmain(String[]args){
GestorTareasgt=newGestorTareas(10);

try{
gt.nuevaTarea(newTPReloj());
gt.nuevaTarea(newTPAviso("Hapasado5segundos",5));
}catch(DemasiadasTareasdt){
System.out.println("Mmmm....estonodeberahaberpasado");
}

gt.start();

System.out.println("Hilodeejecucinprincipal");
System.out.println("Pulsaunateclaparaterminar");

try{
System.in.read();
}
catch(IOExceptione){}

System.out.println("Finaldeaplicacin");
gt.terminar();
}
}
Otrostemasde
intersenJava

También podría gustarte