Está en la página 1de 127

Programacinorientadaa

objetosenJava

Tema2: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