Está en la página 1de 127

Programacinorientadaa

objetosenJava

Tema2:Programacinorientadaa
objetosenJava
1.Clasesdeobjetos 14.Herenciamltiple
2.Proteccindemiembros 15.Polimorfismo
3.Proteccindeclases 16.Ligaduradinmica
4.Inicializacinyfinalizacin 17.Informacindeclasesentiempo
5.Creacindeobjetos deejecucin
6.Trabajandoconobjetos 18.OtrostemasdeintersenJava
7.Relacionesentreobjetos
8.Clasesanidadaseinteriores
9.Autoreferencias
10.Aplicacionesorientadasaobjetos
11.Herencia
12.Adicin,redefinicinyanulacin
13.Proteccinyherencia
Programacinorientadaa
objetosenJava

Clasesdeobjetos
Lasclasesdeobjetosrepresentanconceptoso
entidadessignificativosenunproblemadeterminado.
Unaclasedescribelascaractersticascomunesdeun

conjuntodeobjetos,mediantedoselementos:
Atributos(ovariablesmiembro,variablesdeclase).Describenelestadointerno
decadaobjeto
Operaciones(omtodos,funcionesmiembro).Describenloquesepuedehacer
conelobjeto,losserviciosqueproporciona

Cuenta Nombredelaclase

nmero:String
titular:String
Atributos
saldo:Float
interesAnual:Float

ingreso(cantidad:Floatl)
reintegro(cantidad:Floatl)
Operaciones ingresoInteresMes()
enRojos():Boolean
leerSaldo():Real
Clasesdeobjetos
Programacinorientadaa
objetosenJava

Durantelaejecucindelaaplicacinseproducirla
instanciacindelaclase,esdecir,lacreacindelos
objetosquerepresentancadaunodelosindividuos
consuscaractersticaspropias,esdecir,valores
especficosparasusatributos
c:Cuenta

Cuenta numero=123890023
titular=MiguelPrez
saldo=1800.4 e:Cuenta
nmero:String
titular:String intersAnual=0.25
numero=151590020
saldo:Float titular=Javier
interesAnual:Float Snchez
saldo=1200.2
ingreso(cantidad:Floatl) intersAnual=1.25
reintegro(cantidad:Floatl)
ingresoInteresMes() d:Cuenta
enRojos():Boolean
leerSaldo():Real numero=23900839
titular=Antonio
Gmez
Clasedeobjetos
saldo=200
intersAnual=0.25

Objetos
Clasesdeobjetos
Programacinorientadaa
objetosenJava

LaimplementacindeestaclaseenJavaserealizaraenunficheroconnombre
Cuenta.java,ysucontenidoseraelsiguiente:

classCuenta{
longnumero;
Stringtitular;
Atributos
floatsaldo;
floatinteresAnual;

voidingreso(floatcantidad){}
voidreintegro(floatcantidad){}
Operaciones 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()

Proteccinde
*Lasveremosmsadelante,alestudiarelmecanismodelaherencia miembros
Programacinorientadaa
objetosenJava

EnJavaunmiembroseetiquetacomopblicocolo
candoelidentificadorpublicdelantedesudeclaracin
Paralosmiembrosprivadosutilizaremosel

identificadorprivate
classCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
Cuenta
publicvoidingreso(floatcantidad){
numero:Long saldo+=cantidad;
titular:String
}
saldo:Float
intersAnual:Real
publicvoidreintegro(floatcantidad){
+ingreso(cantidad:Integer) saldo=cantidad;
+reintegro(cantidad:Integer) }
+ingresoInteresMes()
+enRojos():Boolean publicvoidingresoInteresMes(){
+leerSaldo():Integer 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; classD{
... LasclasesA,ByCsonamigasalpertenecer
classA{ classC{ } almismopaqueteprueba
... ...
LasclasesDyEsonamigasalperteneceral
} } classE{ mismoficherofuente
...
classB{ }
...
} 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 A

B
C 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

Creacindeobjetos
*VaseelapartadoCharactersandStringsdeltutorialdeJavadeSunparamsinformacin
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*

Relacionesentre
*Laveremosmsadelante,enunapartadoespecfico objetos
Programacinorientadaa
objetosenJava

Ladependenciaeslarelacinmenosimportante.
Simplementereflejaquelaimplementacindeuna
clasedependedeotra
Unadependenciapuedeindicarlautilizacindeun

objetodeunaclasecomoargumentodeunaoperacin
deotraoensuimplementacin
Comovimosanteriormente,laclaseCuentarequierelasclasesFileOutputStreamy
ObjectOutputStreamdelalibreradeclasesdeJavaparalaimplementacindela
operacinsalvar

Cuenta

numero:Long
titular:String java.io.FileOutputStream
saldo:Float
intersAnual:Float
java.io.ObjectOutputStream
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+salvar()
Relacionesentre
objetos
Programacinorientadaa
objetosenJava

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

sentidodedicharelacinylascardinalidadesenlos
dosextremos
VamosasustituirelatributotitularporunaasociacinconunanuevaclaseCliente
completa
Cuenta
Cliente
numero:Long titular
saldo:Float 1 nombre:String
*

intersAnual:Float apellidos:String
direccin:String
+ingreso(cantidad:Integer) localidad:String
+reintegro(cantidad:Integer) fNacimiento:Date
+ingresoInteresMes()
+enRojos():Boolean +nombreCompleto():String
+leerSaldo():Integer +direccionCompleta():String
+leerTitular():Cliente Relacionesentre
+salvar()
objetos
Programacinorientadaa
objetosenJava

UnaasociacinseimplementaenJavaintroduciendo
referenciasaobjetosunaclasecomoatributosenla
otra
Silarelacintieneunacardinalidadsuperiorauno

entoncessernecesarioutilizarunarrayde
referencias.Tambinesposibleutilizarunaestructura
dedatosdinmicadelpaquetejava.utilcomoVectoro
LinkedListparaalmacenarlasreferencias
Normalmentelaconexinentrelosobjetosserealiza

recibiendolareferenciadeunodeellosenel
constructorounaoperacinordinariadelotro

Relacionesentre
objetos
Programacinorientadaa
objetosenJava
publicclassCliente{
privateStringnombre,apellidos;
privateStringdireccion,localidad;
privateDatefNacimiento;

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

formadopor
Polgono Segmento
2 *

disponede
Departamento Despacho
1 *

Relacionesentre
objetos
Programacinorientadaa
objetosenJava

Lacomposicinesuntipodeagregacinqueaadeel
matizdequelaclasetodocontrolalaexistenciadelas
clasesparte.Esdecir,normalmentelaclasetodo
crearalprincipiolasclasesparteyalfinalse
encargardesudestruccin
SupongamosqueaadimosunregistrodemovimientosalaclaseCuenta,deforma
quequedeconstanciatrascadaingresooreintegro
Cuenta
Cliente
numero:Long titular
saldo:Float 1 nombre:String
*

intersAnual:Float apellidos:String
direccin:String
+ingreso(cantidad:Integer) localidad:String
+reintegro(cantidad:Integer) fNacimiento:Date
+ingresoInteresMes()
+enRojos():Boolean +nombreCompleto():String
+leerSaldo():Integer +direccionCompleta():String
registra
+leerTitular():Cliente
+salvar()
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

$ls
BancoApp.javaCliente.javaCuenta.java
$javac*.java
Lamquinavirtualjava $ls
producirunerrorsise BancoApp.classCliente.classCuenta.classMovimiento.class
lepasaunaclasesin BancoApp.javaCliente.javaCuenta.java
laoperacinmain $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

C D

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
registra
CuentaConHistorico fecha:Date
* tipo:Char
recuperar() importe:Real
salvar() 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
reintegro() cotizacion:Float
ingresoMes() numCuentaOrigen:String

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) escribir(e:Elemento,c:Clave)
leer(pos:Integer):Elemento leer(c:Clave):Elemento
borrar(pos:Integer) borrar(c:Clave)

Vector Lista TablaHash

buffer[nelem]:Elemento cabecera:Nodo tabla[nelem]:Elemento

redimensionar(t:Integer) insertar(e:Elemento,pos:Integer) funcionHash(c:Clave):Integer


insertaPrin(e:Elemento)
insertarFinal(e:Elemento)

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
+leerHora():String
+leerMsg():String +leerCmd():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
Programacinorientadaa
objetosenJava
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;

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

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

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

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

C D

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 TPAviso TPEjecucion

msg:String cmd:String
+leerHora():String
+ejecutarTarea() +leerMsg():String +leerCmd():String
+ejecutarTarea() +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
Programacinorientadaa
importjava.lang.Runtime;
importjava.io.IOException; 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 TPEjecucion TPAviso

cmd:String msg:String
+leerHora():String
+necesitaEjecucion():Boolean +leerCmd():String +leerMsg():String
+actualizarReloj() +necesitaEjecucion():Boolean +necesitaEjecucion():Boolean
+ejecutarTarea() +actualizarReloj() +actualizarReloj()
+activar() +ejecutarTarea() +ejecutarTarea()
+desactivar() +activar() +activar()
+desactivar() +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
almacena
FiguraGeometrica Lista 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

atributoX
A B

atributoX atributoX

A B

C
C

Herenciamltiple
Programacinorientadaa
objetosenJava

LaapuestadeloscreadoresdeJavaesclara:no
permitirlaherenciamltiple,porlasrazonesexpuestas
anteriormente
Avecesesposiblesustituirlaherenciamltiplepor

unacombinacinherencia/composicin,aunqueel
resultadonopuedeconsiderarseequivalente
FiguraGeometrica

contiene almacena
Poligono Lista Segmento
1 *

listaPuntos():Lista

FiguraGeometrica

contiene almacena
Poligono Lista Segmento
1 *

aadir(s:Segmento) aadir(s:Segmento)
borrarPrim()
borrarUlt() Herenciamltiple
Programacinorientadaa
objetosenJava

Adems,Javasquepermitelaimplementacinde
unaovariasinterfacesademsdelaherencia,loque
puedeconsiderarseunaformarestringidadeherencia
mltiple
Unaclasepuedeheredardeotraeimplementarunao

variasinterfacessinqueaparezcanlosproblemas
asociadosconlaherenciamltiple

<<interfaz>> almacena
FiguraGeometrica Lista Segmento
*

Poligono

Herenciamltiple
Programacinorientadaa
objetosenJava

Polimorfismo
Sondosmecanismosrelacionadosqueotorganala
OOPunagranpotenciafrenteaotrosparadigmasde
programacin
nicamentetienensentidoporlaexistenciadela

herencia
Elpolimorfismo(oupcasting)consisteenlaposibilidad

dequeunareferenciaaobjetosdeunaclasepueda
conectarsetambinconobjetosdedescendientesde
sta
objeto:A
B rb:B
Ara=newA();//Asignacinordinaria

Brb=ra;//Asignacinpolimorfa ra:A
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
A

f()
Ar=?? CALL_A_f?
r.f() CALL_B_f?
B C

CALL_C_f?
f() 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