Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Poo en Java
Poo en Java
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