Documentos de Académico
Documentos de Profesional
Documentos de Cultura
objetosenJava
Programacinorientadaa
objetosenJava
1.Clasesdeobjetos
2.Proteccindemiembros
3.Proteccindeclases
4.Inicializacinyfinalizacin
5.Creacindeobjetos
6.Trabajandoconobjetos
7.Relacionesentreobjetos
8.Clasesanidadaseinteriores
9.Autoreferencias
10.Aplicacionesorientadasaobjetos
11.Herencia
12.Adicin,redefinicinyanulacin
13.Proteccinyherencia
14.Herenciamltiple
15.Polimorfismo
16.Ligaduradinmica
17.Informacindeclasesentiempo
deejecucin
18.OtrostemasdeintersenJava
Programacinorientadaa
objetosenJava
Clasesdeobjetos
Lasclasesdeobjetosrepresentanconceptoso
entidadessignificativosenunproblemadeterminado.
Unaclasedescribelascaractersticascomunesdeun
conjuntodeobjetos,mediantedoselementos:
Atributos(ovariablesmiembro,variablesdeclase).Describenelestadointerno
decadaobjeto
Operaciones(omtodos,funcionesmiembro).Describenloquesepuedehacer
conelobjeto,losserviciosqueproporciona
Cuenta
Atributos
Operaciones
Nombredelaclase
nmero:String
titular:String
saldo:Float
interesAnual:Float
ingreso(cantidad:Floatl)
reintegro(cantidad:Floatl)
ingresoInteresMes()
enRojos():Boolean
leerSaldo():Real
Clasesdeobjetos
Programacinorientadaa
objetosenJava
Durantelaejecucindelaaplicacinseproducirla
instanciacindelaclase,esdecir,lacreacindelos
objetosquerepresentancadaunodelosindividuos
consuscaractersticaspropias,esdecir,valores
especficosparasusatributos
c:Cuenta
Cuenta
nmero:String
titular:String
saldo:Float
interesAnual:Float
ingreso(cantidad:Floatl)
reintegro(cantidad:Floatl)
ingresoInteresMes()
enRojos():Boolean
leerSaldo():Real
Clasedeobjetos
numero=123890023
titular=MiguelPrez
saldo=1800.4
intersAnual=0.25
e:Cuenta
numero=151590020
titular=Javier
Snchez
saldo=1200.2
intersAnual=1.25
d:Cuenta
numero=23900839
titular=Antonio
Gmez
saldo=200
intersAnual=0.25
Objetos
Clasesdeobjetos
Programacinorientadaa
objetosenJava
LaimplementacindeestaclaseenJavaserealizaraenunficheroconnombre
Cuenta.java,ysucontenidoseraelsiguiente:
Atributos
Operaciones
classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;
voidingreso(floatcantidad){}
voidreintegro(floatcantidad){}
voidingresoInteresMes(){}
booleanenRojos(){}
floatleerSaldo(){}
}
Losatributospuedenserdecualquieradelostipos
bsicosdeJava:boolean,char,byte,short,int,long,
floatydouble,referenciasaotrosobjetosoarrays
deelementosdealgunodelostiposcitados
Clasesdeobjetos
Programacinorientadaa
objetosenJava
AlcontrarioqueC++,Javarealizaladefinicine
implementacindelaclaseenelmismolugar,enun
nicofichero.java
classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;
voidingreso(floatcantidad){
saldo+=cantidad;
}
voidreintegro(floatcantidad){
saldo=cantidad;
}
voidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
booleanenRojos(){returnsaldo<0;}
floatleerSaldo(){returnsaldo;}
}
Clasesdeobjetos
Programacinorientadaa
objetosenJava
Elaccesoalosatributosdelaclasedesdela
implementacindelasoperacionesserealizade
formadirecta
Losatributosuoperacionesestticas(static)noson
afectadosporelprocesodeinstanciacindeobjetos
apartirdelaclase
Deunatributoestticonosegeneraunacopiapor
cadaobjetoquesecrea.Existeunanicacopia
compartidayaccesibledesdetodoslosobjetosdela
clase
Unaoperacinestticanicamentepuedeaccedera
miembrosestticos
Clasesdeobjetos
Programacinorientadaa
objetosenJava
ElatributonOpmantieneunacuentaglobaldelnmerodeoperaciones
realizadasenlascuentasdelbanco,paralarealizacindeestadsticas.La
operacinleerNOperaciones()permiteleerestecontador
LaoperacineurosAPesetas()esunaoperacinauxiliardelaclaseCuentapara
serusadacuandoseanecesariaunaconversindemoneda
classCuenta{
longnumero;
Stringtitular;
floatsaldo;
floatinteresAnual;
//Contadordeoperaciones
staticintnOp=0;
staticintleerNOperaciones(){returnnOp;}
//Operacinestticaauxiliardeconversin
staticlongeurosAPesetas(floateuros){returneuros*166.386f;}
voidingreso(floatcantidad){saldo+=cantidad;++nOp;}
voidreintegro(floatcantidad){saldo=cantidad;++nOp;}
}
Clasesdeobjetos
Programacinorientadaa
objetosenJava
Proteccindemiembrosdelaclase
Elprincipiodeocultacindeinformacinseplasma
enloslenguajesOOendiversosmecanismosde
proteccindelosmiembrosdelaclase
UMLpermiteasociartresnivelesdeproteccin
diferentesacadamiembrodelaclase:
Miembrospblicos(+).Sinningntipodeproteccinespecial
Miembrosprivados().Inaccesiblesdesdeelexteriordelaclase
Miembrosprotegidos(#).Similaresalosprivadosaunquesepermitesuacceso
desdelasclasesdescendientes*
Clase
atributoPrivado:Tipo
+atributoPublico:Tipo
#atributoProtegido:Tipo
operacionPrivada()
+operacionPublica()
#operacionProtegida()
*Lasveremosmsadelante,alestudiarelmecanismodelaherencia
Proteccinde
miembros
Programacinorientadaa
objetosenJava
EnJavaunmiembroseetiquetacomopblicocolo
candoelidentificadorpublicdelantedesudeclaracin
Paralosmiembrosprivadosutilizaremosel
identificadorprivate
Cuenta
numero:Long
titular:String
saldo:Float
intersAnual:Real
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
classCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Proteccinde
miembros
Programacinorientadaa
objetosenJava
Losmiembrosnoetiquetadossonaccesiblesporparte
declasesamigas.EnC++yotroslenguajesOOlas
clasesamigasaunadadapuedenindicarse
explcitamente
EnJavaseconsideranamigastodasaquellasque
formanpartedelmismopaquete
Unficherofuentejavaformaensunpaqueteyportantotodaslasclasesincluidas
enlsonamigas
Lasclasesincluidasenvariosficherosfuentepuedenagruparseenunnico
paqueteindicandoelnombredepaquetealprincipiodecadaficheromedianteel
indicadorpackage
packageprueba;
packageprueba;
classA{
...
}
classC{
...
}
classB{
...
}
classD{
...
}
classE{
...
}
LasclasesA,ByCsonamigasalpertenecer
almismopaqueteprueba
LasclasesDyEsonamigasalperteneceral
mismoficherofuente
Proteccinde
miembros
Programacinorientadaa
objetosenJava
Enesteejemplo,lasclasesCuentayBancosonamigasalperteneceralmismo
ficherofuente.ElaccesoalosatributosdelosobjetosdelaclaseCuentaalmacenados
enelvectorinternodeBancoquedaasgarantizado.Elatributosaldopuede
mantenersecomoprivadopuestoqueexisteunaoperacinquepermiteobtenersu
valor:
classCuenta{
longnumero;
Stringtitular;
privatefloatsaldo;
floatinteresAnual;
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
classBanco{
Cuenta[]c;//vectordecuentas
...
}
Proteccinde
miembros
Programacinorientadaa
objetosenJava
Atencin:todaslasclasesquenosedeclarencomo
pertenecientesaningnpaquetedeformaexplcita,
pertenecenaunpaquetepordefectoyportantoson
amigas
Unpaquetecreaunespaciodenombrespropios.Esto
significaquelaclasepasaatenercomoprefijoel
propionombredelpaquete.Alahoradeutilizarla
tenemostresopciones:
Utilizarsunombrecompleto:prueba.A
Importaresaclase,parapoderutilizarlasinelprefijo.Estoseindicaalprincipiodel
cdigofuentemedianteimportprueba.A
Importardirectamentetodaslasclasesdelpaquete,queseusaransinprefijo:
importprueba.*
Proteccinde
miembros
Programacinorientadaa
objetosenJava
Unpaquetepuedeestarsituadodentrodeotro
paqueteformandoestructurasjerrquicas.Ejemplo:
miapp.prueba.A
Javaobligaaqueexistaunacorrespondenciaentrela
estructuradepaquetesdeunaclaseylaestructurade
directoriosdondeestsituada
Laraizdelaestructuradedirectoriosdebeestar
incluidaenelclasspathdeJava(parmetrocp<dir>)
Lasclasesmiapp.prueba.A,miapp.prueba.Bymiapp.Cdebenestarenlasiguiente
estructuradedirectorios:
miapp
prueba
C
A
B
Proteccinde
miembros
Programacinorientadaa
objetosenJava
Proteccindeclases
Porproteccindeclasesentendemosunnivelsuperior
delaocultacindeinformacin,aniveldeclases.Es
decir,setratadeespecificarqueclasespuedenser
utilizadasycualesno,yporquin
Dentrodeunpaquete,lasclasessonamigasypor
tantonoexistenrestriccionesrespectoalautilizacin
deunaclaseporlasotras
Sinembargo,desdeelpuntodevistadelexterior,
nicamentepodrnserutilizadaslasclasespblicas
delpaquete,esdecir,aquellasconelidentificador
publicsituadodelantedesudeclaracin
Proteccindeclases
Programacinorientadaa
objetosenJava
Atencin:Javaslopermiteunaclasepblicapor
ficherofuente,yelnombredelaclaseyelfichero
debencoincidirobligatoriamente
Ennuestroejemplo,siqueremosquelaclaseCuentapuedaserutilizadadesdeel
exteriordelficheroCuenta.javadeberemosdeclararlacomopblica
publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Proteccindeclases
Programacinorientadaa
objetosenJava
Inicializacinyfinalizacin
Lainiciacindelosatributosdelaclaseserealizaen
Java,aligualqueenC++,medianteelusode
constructorescuyonombrecoincideconeldelaclase
publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
Cuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Javapermitelasobrecargadeoperaciones,portanto
sepuedendefinirvariosconstructoresposibleparauna
clasesiemprequesediferencienenlalistade
argumentos
//Importartodaslasclasesdelpaquetejava.io
importjava.io.*;
publicclassCuenta{
privatelongnumero;
privateStringtitular;
privatefloatsaldo;
privatefloatinteresAnual;
//Constructorgeneral
Cuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
//Constructorparaobtenerlosdatosdelacuentadeunfichero
Cuenta(longaNumero)throwsFileNotFoundException,IOException,
ClassNotFoundException{
FileInputStreamfis=newFileInputStream(aNumero+.cnt);
ObjectInputStreamois=newObjectInputStream(fis);
numero=aNumero;
titular=(String)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
ois.close();
}
publicvoidingreso(floatcantidad){
saldo+=cantidad;
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
}
publicvoidingresoInteresMes(){
saldo+=interesAnual*saldo/1200;
}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Nota:vaseelapartadoI/O:ReadingandWritingdeltutorialJavadeSuncomoapoyoparaentender
elcdigodelnuevoconstructor
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Sinoseproporcionaningnconstructor,Java
proporcionaautomticamenteunconstructorpor
defecto,quenorecibeargumentosyrealizauna
inicializacinpordefectodelosatributos
Unavezimplementadounconstructorpropioporparte
delprogramador,Javaeliminadichoconstructor,
aunquepuedeserdefinidonuevamentedemanera
explcita
Cuenta(){
numero=00000000;
titular=ninguno;
saldo=0;
interesAnual=0;
}
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Naturalmentelosconstructorespuedensermarcados
comopblicos,privados,protegidosoconaccesoa
niveldepaquete,loqueespecificarquienpuedecrear
objetosdeestaclaseydequemanera
//Constructorgeneral
publicCuenta(longaNumero,StringaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
//Constructorparaobtenerlosdatosdelacuentadeunfichero
publicCuenta(longaNumero)throwsFileNotFoundException,
IOException,ClassNotFoundException{
FileInputStreamfis=newFileInputStream(aNumero+.cnt);
ObjectInputStreamois=newObjectInputStream(fis);
numero=aNumero;
titular=(String)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
ois.close();
}
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Cuandofinalizaelusodeunobjeto,esfrecuentela
realizacindeciertastareasantesdesudestruccin,
principalmentelaliberacindelamemoriasolicitada
durantesuejecucin.EstoserealizaenC++yotros
lenguajesOOenlosdenominadosdestructores
Estosdestructoressonoperacionesinvocadas
automticamentejustoantesdeladestruccindel
objeto
Sinembargo,enJavalaliberacindememoriase
realizademaneraautomticaporpartedelrecolector
debasura,portantolanecesidaddeestetipode
operacionesnoexisteenlamayorpartedeloscasos
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Sinembargospuedesernecesariorealizaralguna
tareanorelacionadaconlaliberacindememoria
antesdeladestruccindelobjeto,comoporejemplo
salvarelestadodelaclaseenunficheroobasede
datos
Javapermiteintroducircdigoparaestefin
implementandounaoperacinpblicaespecial
denominadafinalize.Estaoperacinesinvocada
automticamenteantesdeladestruccindelobjetopor
partedelrecolectordebasura
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Siguiendonuestroejemplo,vamosasegurarnosdequeelestadodeunacuenta
quedasalvadoendiscoantesdesudestruccin,parapoderserrecuperada
posteriormente.Paraellointroducimoselcdigodeescrituraenficheroenla
operacinfinalizedelaclaseCuenta
publicvoidfinalize():throwsFileNotFoundException,IOException{
FileOutputStreamfos=newFileOutputStream(numero+.cnt);
ObjectOutputStreamoos=newObjectOutputStream(fos);
oos.writeObject(titular);
oos.writeFloat(saldo);
oos.writeFloat(interesAnual);
oos.close();
}
Problema:noesposiblesaberconseguridadenque
momentoserinvocadafinalize,puestoqueel
recolectordebasurapuededecidirsueliminacinenun
momentoindeterminado,einclusonosereliminado
hastaelfinaldelaejecucindelaaplicacin
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Unaposiblesolucinesordenaralrecolectorde
basuraquerealiceunalimpiezadememoriainmediata,
paraasegurarlafinalizacindelosobjetos.Estose
realizamedianteRuntime.getRuntime().gc()
Pormotivosdeeficiencia,loanteriorespoco
recomendable,sobretodosisehaceconfrecuencia
Unamejoropcinesdefinirunaoperacinordinaria
conestemismopropsito,allamardemaneraexplcita
cuandohayafinalizadoelusodelobjeto
IntroduciremosenlaclaseCuentaunaoperacinpblicasalvarenlugardefinalize,
conlamismaimplementacin.Trasfinalizarlasoperacionessobrelacuenta,
invocaremosasalvarparaguardarloscambiosrealizados
Inicializaciny
finalizacin
Programacinorientadaa
objetosenJava
Creacindeobjetos
EnJavalosobjetossecreannicamentedeforma
dinmica.Paraelloseutilizaeloperadornew,de
manerasimilaraC++
LosobjetosenJavaseutilizansiempreatravsde
referencias.Lasreferenciassonsimilaresalos
punterosdeC/C++,aunquesuusoesmuchoms
sencillo
Portantolospasosaseguirenlacreacindeun
objetoson:
Declararunareferenciaalaclase
Crearunobjetomedianteeloperadornewinvocandoalconstructoradecuado
Conectarelobjetoconlareferencia
Creacindeobjetos
Programacinorientadaa
objetosenJava
LacreacindeunobjetodelaclaseCuentaserealizaradelasiguienteforma:
Cuentac;//UnareferenciaaunobjetodelaclaseCuenta
c=newCuenta(18400200,PedroJimnez,0.1f);
Encambio,lostiposbsicos(int,long,float,etc.)s
puedensercreadosdirectamenteenlapila.Estoes
posibleporqueJavanolosimplementarealmentecomo
clasesdeobjetos,pormotivosdeeficienciay
comodidad,yaquesuusoesmuyfrecuente
Cuentac;
floatin;
longnum;
in=0.1f;
num=18400200;
c=newCuenta(num,PedroJimnez,in);
Creacindeobjetos
Programacinorientadaa
objetosenJava
Lascadenasdecaracteresseimplementanconuna
clase(String).Sinembargonosuelesernecesariasu
creacindemaneraexplcita,yaqueJavalohacede
maneraautomticaalasignarunacadenaconstante*
Strings;//UnareferenciaaunobjetodelaclaseString
//ConexindelareferenciasconunobjetoString
//creadodinmicamenteeinicializadoconlaconstantePedro
s=Pedro;
//Seraequivalentea:
//char[]cc={'P','e','d','r','o'}
//s=newString(cc);
Losarraystambindebensercreadosdinmicamente
connewcomosifueranobjetos
int[]v;//Unareferenciaaunvectordeenteros
v=newint[10]//Creacindeunvectorde10enteros
*VaseelapartadoCharactersandStringsdeltutorialdeJavadeSunparamsinformacin
Creacindeobjetos
Programacinorientadaa
objetosenJava
Sielarrayesdereferenciasaobjetos,habrquecrear
ademscadaunodelosobjetosreferenciadospor
separado
Cuenta[]v;//UnvectordereferenciasaobjetosdelaclaseCuenta
intc;
v=newCuenta[10]//Crearespaciopara10referenciasacuentas
for(c=0;c<10;c++)
v[c]=newCuenta(18400200+c,Clienten.+c,0.1f);
Ladestruccindelosobjetosserealizademanera
automticacuandoelrecolectordebasuradetectaque
elobjetonoestsiendousado,esdecir,noest
conectadoaningunareferencia
Cuentac1=newCuenta(18400200,Cliente1,0.1f);
Cuentac2=newCuenta(18400201,Cliente2,0.1f);
c1=c2
//Elobjetoasociadoalacuenta18400200ha
//quedadodesconectadoysereliminadoporel
//recolectordebasura
Creacindeobjetos
Programacinorientadaa
objetosenJava
Trabajandoconobjetos
TrabajarconunobjetoJavaessimilaraC++,aunque
lasreferenciaspermitenunusomuchomssencillo
Cuentac1=newCuenta(18400200,PedroJimnez,0.1f);
Cuentac2=newCuenta(18400201);
c2.reintegro(1000);
c1.ingreso(500);
if(c2.enRojos())
System.out.println(Atencin:cuenta18400201ennmerosrojos);
System.out.println(Saldoactualdelacuenta18400201:+c1.leerSaldo());
c1=newCuenta(18400202);
//ElobjetoasociadoalaCuenta18400200quedadesconectado
c1.ingreso(500);
System.out.println(Saldoactualdelacuenta18400202:+c1.leerSaldo());
Trabajandocon
objetos
Programacinorientadaa
objetosenJava
Enesteejemplosepideunnmerodecuentaalusuarioyunacantidadaretirar.A
continuacinsecargalacuentasolicitadayserealizaelreintegro
BufferedReaderbr=newBufferedReader(InputStreamReader(System.in));
longnc;
floatmi;
try{
System.out.println(Introduzcanm.dedecuenta:);
nc=Long.parseLong(br.readLine());
System.out.println(Introduzcaimportearetirar:);
mi=Float.parseFloat(br.readLine());
}
catch(Exceptione){
System.out.println(Erroralleerdatos);
return;
}
Cuentac;
try{
c=newCuenta(nc);
}
catch(Exceptione){
System.out.println(Imposiblerecuperarcuenta);
return;
}
if(c.leerSaldo()<mi)
System.out.println(Saldoinsuficiente);
else
c.reintegro(mi);
c.salvar();
Trabajandocon
objetos
Programacinorientadaa
objetosenJava
Naturalmenteelcompiladorproducirunerrorante
cualquieraccesoilegalaunmiembrodelaclase
Cuentac=newCuenta(18400200,PedroJimnez,0.1f);
c.saldo=1000;
Cuenta.java:XX:saldohasprivateaccess
c.saldo=1000;
^
1error
Elaccesoaunmiembroestticoserealizautilizando
elnombredelaclaseenlugardeunobjeto
Cuentac=newCuenta(18400200,Cliente1,0.1f);
c.ingreso(1000);
intpts=Cuenta.eurosAPesetas(c.leerSaldo());
System.out.println(Saldo:+c.leerSaldo()+(+pts+pesetas);
Trabajandocon
objetos
Programacinorientadaa
objetosenJava
Relacionesentreobjetos
Unconjuntodeobjetosaisladostieneescasa
capacidadpararesolverunproblema.Enuna
aplicacinreallosobjetoscolaboraneintercambian
informacin,existiendodistintostiposderelaciones
entreellos
Aniveldediseo,podemosdistinguirentre5tiposde
relacionesbsicasentreclasesdeobjetos:
dependencia,asociacin,agregacin,composiciny
herencia*
*Laveremosmsadelante,enunapartadoespecfico
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Ladependenciaeslarelacinmenosimportante.
Simplementereflejaquelaimplementacindeuna
clasedependedeotra
Unadependenciapuedeindicarlautilizacindeun
objetodeunaclasecomoargumentodeunaoperacin
deotraoensuimplementacin
Comovimosanteriormente,laclaseCuentarequierelasclasesFileOutputStreamy
ObjectOutputStreamdelalibreradeclasesdeJavaparalaimplementacindela
operacinsalvar
Cuenta
numero:Long
titular:String
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+salvar()
java.io.FileOutputStream
java.io.ObjectOutputStream
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Encambio,laasociacineslarelacinmsimportante
ycomn.Reflejaunarelacinentredosclases
independientesquesemantienedurantelavidadelos
objetosdedichasclasesoalmenosduranteuntiempo
prolongado
EnUMLsueleindicarseelnombredelarelacin,el
sentidodedicharelacinylascardinalidadesenlos
dosextremos
VamosasustituirelatributotitularporunaasociacinconunanuevaclaseCliente
completa
Cuenta
numero:Long
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+leerTitular():Cliente
+salvar()
Cliente
titular
*
nombre:String
apellidos:String
direccin:String
localidad:String
fNacimiento:Date
+nombreCompleto():String
+direccionCompleta():String
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
UnaasociacinseimplementaenJavaintroduciendo
referenciasaobjetosunaclasecomoatributosenla
otra
Silarelacintieneunacardinalidadsuperiorauno
entoncessernecesarioutilizarunarrayde
referencias.Tambinesposibleutilizarunaestructura
dedatosdinmicadelpaquetejava.utilcomoVectoro
LinkedListparaalmacenarlasreferencias
Normalmentelaconexinentrelosobjetosserealiza
recibiendolareferenciadeunodeellosenel
constructorounaoperacinordinariadelotro
Relacionesentre
objetos
publicclassCliente{
privateStringnombre,apellidos;
privateStringdireccion,localidad;
privateDatefNacimiento;
Programacinorientadaa
objetosenJava
Cliente(StringaNombre,StringaApellidos,StringaDireccion,
StringaLocalidad,DateaFNacimiento){
nombre=aNombre;
apellidos=aApellidos;
direccion=aDireccion;
localidad=aLocalidad;
fNacimiento=aFNacimiento;
}
StringnombreCompleto(){returnnombre++apellidos;}
StringdireccionCompleta(){returndireccion+,+localidad;}
}
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
}
ClienteleerTitular(){returntitular;}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Laagregacinesuntipoespecialdeasociacindonde
seaadeelmatizsemnticodequelaclasededonde
partelarelacinrepresentaeltodoylasclases
relacionadaslaspartes
RealmenteJavaylamayoradelenguajesorientados
aobjetosnodisponendeunaimplementacinespecial
paraestetipoderelaciones.Bsicamentesetratan
comolasasociacionesordinarias
Polgono
Departamento
formadopor
2
Segmento
disponede
1
Despacho
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Lacomposicinesuntipodeagregacinqueaadeel
matizdequelaclasetodocontrolalaexistenciadelas
clasesparte.Esdecir,normalmentelaclasetodo
crearalprincipiolasclasesparteyalfinalse
encargardesudestruccin
SupongamosqueaadimosunregistrodemovimientosalaclaseCuenta,deforma
quequedeconstanciatrascadaingresooreintegro
Cuenta
numero:Long
saldo:Float
intersAnual:Float
+ingreso(cantidad:Integer)
+reintegro(cantidad:Integer)
+ingresoInteresMes()
+enRojos():Boolean
+leerSaldo():Integer
+leerTitular():Cliente
+salvar()
Cliente
titular
*
nombre:String
apellidos:String
direccin:String
localidad:String
fNacimiento:Date
+nombreCompleto():String
+direccionCompleta():String
registra
Movimiento
*
fecha:Date
tipo:Char
importe:Real
saldo:Real
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Lascomposicionestienenunaimplementacinsimilar
alasasociaciones,conladiferenciadequeelobjeto
principalrealizarenalgnmomentolaconstruccinde
losobjetoscompuestos
importjava.util.Date
classMovimiento{
Datefecha;
chartipo;
floatimporte;
floatsaldo;
publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldo=aSaldo;
}
}
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
privateLinkedListmovimientos;//Listademovimientos
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Nuevaimplementacindeingresoyreintegro
publicvoidingreso(floatcantidad){
movimientos.add(newMovimiento(newDate(),'I',cantidad,saldo+=cantidad));
}
publicvoidreintegro(floatcantidad){
movimientos.add(newMovimiento(newDate(),'R',cantidad,saldo=cantidad));
}
publicvoidingresoInteresMes(){ingreso(interesAnual*saldo/1200);}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Nota:tambinseranecesariomodificarelotroconstructorylaoperacinsalvarparatenerencuentalalistademovimientos
alahoradeleer/escribirlainformacindelaCuentaendisco
Relacionesentre
objetos
Programacinorientadaa
objetosenJava
Clasesanidadaseinteriores
JavayalgunosotroslenguajesOOPpermitenla
definicindeunaclasedeobjetosdentrodeotra,con
unadobleutilidad:
Organizarmejorelcdigo.Empaquetarenunaclaseprincipalotrasquenotienen
utilidadosentidofueradelcontextodesta
Evitarcolisionesdenombres.Laclaseprincipaldefineunespaciodenombresalque
pertenecenlasanidadas
Aligualquecualquierotromiembrodeunaclase,una
claseanidadapuedeserestticaonoestticayutilizar
losnivelesdeproteccinpublic,privateyprotected
Eltipodeclaseanidamientomssencilloesaquelen
quelaclasecontenidasedeclaracomoesttica
Clasesanidadase
interiores
Programacinorientadaa
objetosenJava
Desdeelpuntodevistadelaorganizacindelcdigo,tendramuchomssentido
introducirlaclaseMovimientoenelinteriordeCuenta.Alserdeclaradacomoprivada,
seimpedirasuutilizacindesdeelexterior
importjava.util.Date
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo;
privatefloatinteresAnual;
privateLinkedListmovimientos;//Listademovimientos
staticprivateclassMovimiento{
Datefecha;
chartipo;
floatimporte;
floatsaldo;
publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;tipo=aTipo;importe=aImporte;saldo=aSaldo;
}
}
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Clasesanidadase
interiores
Programacinorientadaa
objetosenJava
Cuandolaclaseanidadanoesesttica,sedenomina
claseinteriorytienecaractersticasespeciales:
Puedensercreadasnicamentedentrodelaclasecontinente
Tieneaccesocompletoydirectoatodoslosatributosyoperacionesdelobjetoque
realizasucreacin
Losobjetosdelaclaseinteriorquedanligados
permanentementealobjetoconcretodelaclase
continentequerealizsucreacin
Nodebeconfundirseesteelementoconlarelacinde
composicin,aunqueenmuchoscasosesposible
utilizarclasesinterioresparalaimplementacindeeste
tipoderelaciones
Clasesanidadase
interiores
Programacinorientadaa
objetosenJava
ImplementandolaclaseMovimientocomounaclaseinterioresposiblecopiarel
valordelsaldoactualdelacuentaquerealizaelmovimientodemaneradirecta
importjava.util.Date
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;
privateLinkedListmovimientos;//Listademovimientos
privateclassMovimiento{
Datefecha;
chartipo;
floatimporte,saldoMov;
publicMovimiento(DateaFecha,charaTipo,floataImporte){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldoMov=saldo;//Copamoselsaldoactual
}
}
//SiguelaimplementacindelaclaseCuenta
Clasesanidadase
interiores
Programacinorientadaa
objetosenJava
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;
interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Nuevaimplementacindeingresoyreintegro
publicvoidingreso(floatcantidad){
saldo+=cantidad;
movimientos.add(newMovimiento(newDate(),'I',cantidad));
}
publicvoidreintegro(floatcantidad){
saldo=cantidad;
movimientos.add(newMovimiento(newDate(),'R',cantidad));
}
publicvoidingresoInteresMes(){ingreso(interesAnual*saldo/1200);}
publicbooleanenRojos(){returnsaldo<0;}
publicfloatleerSaldo(){returnsaldo;}
}
Clasesanidadase
interiores
Programacinorientadaa
objetosenJava
Autoreferencias
Enocasionesesnecesarioobtenerunareferenciaen
laimplementacindeunaoperacinalpropioobjeto
sobreelquehasidoinvocadalaoperacin
EstareferenciaseobtieneenC++yJavamedianteel
operadorthis
Cuandoencontremosthisenunaexpresin,podremos
sustituirlomentalmenteporesteobjeto
Aunquenoesnecesario,podemosutilizarthispara
llamardesdelaimplementacindeunaoperacina
otraoperacindelmismoobjeto
Autoreferencias
Programacinorientadaa
objetosenJava
LallamadaalaoperaciningresodesdeingresoInteresMes()puederealizarse
utilizandothiscomoreferenciadelobjetosobreelqueseinvocalaoperacin
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;
publicvoidingresoInteresMes(){this.ingreso(interesAnual*saldo/1200);}
//RestodelasoperacionesdelaclaseCuenta
Enesteejemplo,elusodethisesrealmentetil.Nospermiteimplementarla
operacintransferirDesde()llamandoaunaoperacintransferirHasta(),previamente
implementada
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;
publicvoidtransferirHasta(Cuentac,floatcant){
reintegro(cant);c.ingreso(cant);
}
publicvoidtransferirDesde(Cuentac,floatcant){
c.transferirHasta(this,cant);
}
//RestodelasoperacionesdelaclaseCuenta
Autoreferencias
Programacinorientadaa
objetosenJava
OtrautilidaddethisenJavaesrealizarunallamadaa
unconstructordesdeotroconstructor
publicclassCuenta{
privatelongnumero;
privateClientetitular;
privatefloatsaldo,interesAnual;
//Constructorgeneral
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
//Constructorespecficoparacuentasdeahorro(interesAnual=0.1%)
publicCuenta(longaNumero,ClienteaTitular){
this(aNumero,aTitular,0.1);
}
//RestodelaclaseCuenta
Peroatencin:unconstructornoesunaoperacin
ordinaria.nicamentepuedellamarseaunconstructor
desdeotroconstructorydebeserlaprimerainstruccin
dentrodelaimplementacin
Autoreferencias
Programacinorientadaa
objetosenJava
Aplicacionesorientadasaobjetos
Enunaaplicacinorientadaaobjetosdebeexistiruna
clasequerepresentelapropiaaplicacin.Esteserael
puntodondecomenzaralaejecucindelamisma
EnlenguajesnototalmenteorientadoscomoC++enla
funcinmainsecreaunainstanciadeestaclaseyse
llamaaalgunaoperacincomoejecutarparaarrancar
laaplicacin.Sinembargoestonoesobligatorio,yun
malprogramadorpuederealizarunaaplicacinhbrida,
concdigonoorientadoaobjetos
Aplicaciones
orientadasaobjetos
Programacinorientadaa
objetosenJava
EnunlenguajeorientadoaobjetospurocomoJava
estaclasedeaplicacinesobligatoria.
LamquinavirtualJavaseencargadeinstanciaresta
claseyllamaraunaoperacinespecialconnombre
main.Laexistenciadeestaoperacinespecialeslo
quecaracterizaalaclasedeaplicacin
Laclasedeaplicacindebeserpblicaynotenerningnconstructoroun
constructorpordefecto
Almenosdebeimplementarlaoperacinmain,conlasiguientedeclaracin:public
staticmain(String[]args)
publicclassBancoApp{
publicstaticvoidmain(String[]args){
Cuentac1=newCuenta(18400200,PedroJimnez,0.1f);
c1.ingreso(1000);
System.out.println(Ingresorealizado);
}
}
Aplicaciones
orientadasaobjetos
Programacinorientadaa
objetosenJava
Alahoradeejecutarlaaplicacin,deberindicarse
estaclasealamquinavirtualJava
Trascompilarlosficherosdelaltimaversindenuestroejemplo:Cliente.java,
Cuenta.javayBancoApp.javaobtendremoslosficherosenbytecode:
Cliente.class,Cuenta.class,Movimiento.classyBancoApp.class
Finalmente,pasandolaclaseBancoApp.classalamquinavirtualjavapondremos
enfuncionamientolaaplicacin
Lamquinavirtualjava
producirunerrorsise
lepasaunaclasesin
laoperacinmain
$ls
BancoApp.javaCliente.javaCuenta.java
$javac*.java
$ls
BancoApp.classCliente.classCuenta.classMovimiento.class
BancoApp.javaCliente.javaCuenta.java
$javaCuenta
Exceptioninthreadmainjava.lang.NoSuchMethodError:main
$javaBancoApp
Transferenciarealizada
$
Nota:LasclasesqueconstituyenunaaplicacinJavatambinpuedendistribuirsedemaneramuchomscompacta
enunnicoficheroJAR.Conslteselabibliografaparavercomocreanyutilizanestosficheros
Aplicaciones
orientadasaobjetos
Programacinorientadaa
objetosenJava
Herencia
LaherenciaesunmecanismodelaOOPquepermite
construirunaclaseincorporandodemaneraimplcita
todaslascaractersticasdeunaclasepreviamente
existente.Lasrazonesquejustificansunecesidadson
variadas:
Modeladodelarealidad.Sonfrecuenteslasrelacionesde
especializacin/generalizacinentrelasentidadesdelmundoreal,portantoes
lgicoquedispongamosdeunmecanismosimilarentrelasclasesdeobjetos
Evitarredundancias.Todalafuncionalidadqueaportaunaclasedeobjetoses
adoptadademanerainmediataporlaclasequehereda,portantoevitamosla
repeticindecdigoentreclasessemejantes
Facilitarlareutilizacin.Unaclasenotieneporqulimitarsearecibirunaseriede
caractersticasdeotraclaseporherenciadeformapasiva.Tambindisponende
ciertomargendeadaptacindeestascaractersticas
Soportealpolimorfismo
Herencia
Programacinorientadaa
objetosenJava
SeaunaclaseA.SiunasegundaclaseBheredadeA
entoncesdecimos:
AesunascendienteosuperclasedeB.SilaherenciaentreAyBesdirecta
decimosademsqueAeslaclasepadredeB
BesundescendienteosubclasedeA.SilaherenciaentreAyBesdirecta
decimosademsqueBesunaclasehijadeA
A
EnJava,Eiffel,Smalltalkyotroslenguajesorientados
aobjetospuros,todaslasclasesheredan
automticamentedeunasuperclaseuniversal.EnJava
estasuperclasesedenominaObject
Herencia
Programacinorientadaa
objetosenJava
Existendiferentessituacionesenlasquepuede
aplicarseherencia:
Especializacin.DadounconceptoByotroconceptoAquerepresentauna
especializacindeA,entoncespuedeestablecerseunarelacindeherenciaentre
lasclasesdeobjetosquerepresentanaAyB.Enestassituaciones,elenunciado
AesunBsueleseraplicable
Vehculo
Empleado
Figura
Coche
Contable
Cuadrado
Extensin.Unaclasepuedeservirparaextenderlafuncionalidaddeuna
superclasesinquerepresentenecesariamenteunconceptomsespecfico
Lista
Cuenta
Movimiento
ListaSalvable
CuentaConHistorico
recuperar()
salvar()
registra
*
fecha:Date
tipo:Char
importe:Real
saldo:Real
Herencia
Programacinorientadaa
objetosenJava
Especificacin.Unasuperclasepuedeservirparaespecificarlafuncionalidad
mnimacomndeunconjuntodedescendientes.Existenmecanismosparaobligar
alaimplementacindeunaseriedeoperacionesenestosdescendientes
ObjetoGrfico
seleccionar()
mover()
escalar()
cambiarColor()
pintar()
Texto
Lnea
Cuadrado
Construccin.Unaclasepuedeconstruirseapartirdeotra,simplementeporquela
hijapuedeaprovecharinternamenteparteotodalafuncionalidaddelpadre,
aunquerepresentenentidadessinconexinalguna
Lista
Pila
Herencia
Programacinorientadaa
objetosenJava
Ejemplosdeherencia:
Distintostiposdecuentasbancarias
Cuenta
numero:Long
titular:String
saldo:Float
interes:Float
ingreso()
ingresoInteresMes()
leerSaldo()
transferirHasta()
CuentaCorriente
CuentaAhorroPFijo
PlanPensiones
vencimiento:Date
vencimiento:Date
cotizacion:Float
numCuentaOrigen:String
reintegro()
ingresoMes()
Herencia
Programacinorientadaa
objetosenJava
Elementosdeunainterfazdeusuario
Figura
x,y:Integer
mover(nx:Integer,ny:Integer)
Rectngulo
ancho,alto:Integer
escalar(nx:Integer,ny:Integer
Ventana
titulo:String
pintar()
Editor
Boton
pintar()
accion()
Herencia
Programacinorientadaa
objetosenJava
Estructurasdedatos
Contenedor
nelem:Integer
vaciar()
copiar(c:Contenedor)
tamaa():Integer
vacio():Boolean
Secuencia
ContenedorAsociativo
escribir(e:Elemento,pos:Integer)
leer(pos:Integer):Elemento
borrar(pos:Integer)
escribir(e:Elemento,c:Clave)
leer(c:Clave):Elemento
borrar(c:Clave)
Vector
Lista
TablaHash
buffer[nelem]:Elemento
cabecera:Nodo
tabla[nelem]:Elemento
redimensionar(t:Integer)
insertar(e:Elemento,pos:Integer)
insertaPrin(e:Elemento)
insertarFinal(e:Elemento)
funcionHash(c:Clave):Integer
Herencia
Programacinorientadaa
objetosenJava
VamosaestudiarlaimplementacindelaherenciaenJavamedianteelejemplode
unconjuntodetareasprogramables:TPReloj(actualizarunrelojdigitalcada
segundo),TPAviso(mostrarunavisoperidicamente)yTPEjecucion(ejecucindeun
comandocadaciertotiempo)
TareaPeriodica
periodoSegs:Integer
ultimaej:Date
activa:Boolean
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
TPReloj
TPAviso
TPEjecucion
msg:String
cmd:String
+leerMsg():String
+leerCmd():String
+leerHora():String
Herencia
Programacinorientadaa
objetosenJava
LaclaseTareaPeriodicatienelascaractersticascomunesalostrestiposdetarea:
periododeejecucinensegundos,horadelaltimaejecucinybanderadeestado
activo/inactivo
importjava.util.*;
publicclassTareaPeriodica{
intperiodoSegs;//Periododeejecucin
DateultimaEj;//Horadeltimaejecucin
booleanactiva;
publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
//Constructorparaejecucionescadasegundo
publicTareaPeriodica(){
this(1);
}
//Establecerlaltimaejecucinalahoraactual
publicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}
Herencia
Programacinorientadaa
objetosenJava
LaoperacinejecutarTarearealmentenotieneunaimplementacinconcretaaeste
nivel
publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;
//Calcularlahoradelaprximaejecucin
CalendarcalProximaEj=newGregorianCalendar();
calProximaEj.setTime(ultimaEj);
calProximaEj.add(Calendar.SECOND,periodoSegs);
CalendarcalAhora=newGregorianCalendar();
//Comprobarsihapasadoalahoraactual
return(calProximaEj.before(calAhora));
}
publicvoidejecutarTarea(){
System.out.println("Ejecuciondetarea");
}
publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activa=false;}
}
Herencia
Programacinorientadaa
objetosenJava
Paraqueunaclaseherededeotra,utilizaremosel
indicadorextendsenladeclaracindelaclase
importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{
publicTPReloj(){
periodoSegs=60;//Comprobarcadaminuto
actualizarReloj();
activa=true;
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE);
}
}
Atencin!:Aunqueelcdigodeestasclasescompilaperfectamente,laimplementacindelos
constructoresesformalmenteincorrecta.Msadelanteveremosporqu.
Herencia
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
publicTPAviso(StringaMsg,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
msg=aMsg;
}
Programacinorientadaa
objetosenJava
publicStringleerMsg(){returnmsg;}
}
importjava.lang.Runtime;
importjava.io.IOException;
publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}
Atencin!:Aunqueelcdigodeestasclasescompilaperfectamente,laimplementacindelos
constructoresesformalmenteincorrecta.Msadelanteveremosporqu.
Herencia
Programacinorientadaa
objetosenJava
TodoslasclasesenJavaheredanenltimainstancia
deObject.Inclusosicreamosunaclaseindependiente,
JavalahaceheredarimplcitamentedeObject
Object
#clone():Object
+equals(Objectobj):Boolean
#finalize()
+getClass():Class
+hasCode():int
+notify()
+notifyAll()
+toString():String
+wait()
+wait(timeout:Long)
+wait(timeout:Long,nanos:Integer)
Estohacequelasclasesformenunajerarquacon
Objectcomoraz
Object
...
...
...
...
...
Herencia
Programacinorientadaa
objetosenJava
Enlaimplementacindeunaoperacindelasubclase
noexistediferenciaaparenteentreunatributou
operacinpropiadelaclaseyunatributouoperacin
heredados
Ahorapodemoscrearyusarobjetosdecualquieradelasclasesanteriores.Desdeel
exteriortampocoexistendiferenciasaparentesentrelallamadaaunaoperacin
heredadaopropiadelaclase:
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
TPAvisotpa=newTPAviso(EstudiarProgramacinAvanzada!,60);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
while(!tpa.necesitaEjecucion())
System.println(Esperandoejecucindeaviso...);
System.println(Aviso:+tpa.leerMsg());
}
}
Herencia
Programacinorientadaa
objetosenJava
Lainicializacindelosatributosdeunasuperclaseen
elconstructordeunasubclasepresentavarios
inconvenientesserios:
Resultaredundante.Lasuperclasetieneyaunconstructorquehaceesetrabajo.
Porqurepetircdigoentonces?
Silaclasetieneunalargalistadeascendientes,entonceselconstructorseramuy
largo
Lasuperclasepuedetenerunainicializacincompleja,ylainclusindelcdigode
inicializacinenlasubclasepuederequerirunconocimientoexcesivodela
superclaseporpartedelimplementador
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
publicTPAviso(StringaMsg,intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
}
Herencia
Programacinorientadaa
objetosenJava
Elprocedimientocorrectoconsisteenrealizaruna
llamadaalconstructordelasuperclaseparaquerealice
lainicializacindelosatributosheredados
EnJavaestallamadaalconstructordelasuperclase
serealizaconlaoperacionsuper()seguidadelos
parmetrosdeinicializacindealgunodelos
constructoresdelpadredelaclase
LaimplementacincorrectadelconstructordelaclaseTPAvisoseraportantola
siguiente:
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
}
Herencia
Programacinorientadaa
objetosenJava
Ydelasotrasdossubclases:
importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{
publicTPReloj(){
super(60);
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"
+cal.get(Calendar.MINUTE);
}
}
importjava.lang.Runtime;
importjava.io.IOException;
publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}
Herencia
Programacinorientadaa
objetosenJava
nicamentedebellamarseexplcitamenteaun
constructordelascendienteinmediato
Elconstructordeesteltimorealizarasuvezuna
llamadaaunconstructordesuascendienteinmediatoy
assucesivamentehastainicializartodoslosatributos
heredados
A
super(...)
super(...)
B
super(...)
super(...)
C
Herencia
Programacinorientadaa
objetosenJava
Paraterminar,esposibleimpedirlaherenciaapartir
deunaclasedeclarndolacomofinal
Sinembargo,estaesunacaractersticaquedebeser
utilizadaconprudencia,yaquepuederestringiren
excesolaextensinyreutilizacindelasclasesdel
sistemaenelfuturo
importjava.lang.Runtime;
importjava.io.IOException;
finalpublicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
}
Herencia
Programacinorientadaa
objetosenJava
Adicin,redefinicinyanulacin
Laherenciaensnoserataninteresantesinofuera
porlaposibilidaddeadaptareneldescendientelos
miembrosheredados
Adicin.Trivialmenteeldescendientepuedeaadirnuevosatributosyoperaciones
quesesumanalosrecibidosatravsdelaherencia
Redefinicin.Esposibleredefinirlaimplementacindeunaoperacinheredada
paraadaptarlaalascaractersticasdelaclasedescendiente.Tambinesposible
cambiareltipodeunatributoheredado
Anulacin.Cuandounatributouoperacinheredadosnotienenutilidadenel
descendientes,puedenseranuladosparaimpedirsuutilizacin
Notodosloslenguajesorientadosaobjetossoportan
estascaractersticas,enespeciallaanulacin
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
LaredefinicinserealizaenJavaylamayoradelos
lenguajesOOdefiniendonuevamentelaoperacin(con
losmismosargumentos)eneldescendiente
LasclasesdescendientesTPReloj,TPEjecucionyTPAvisonoestnoperativas
todavaporquelaimplementacindeejecutarTarea()quecontieneneslaheredadade
TareaPeriodica,quenohacenadaenparticular
Esprecisoredefinirestaoperacinencadaunadelassubclasesparaquerealicen
lastareascorrespondientes
TareaPeriodica
periodoSegs:Integer
ultimaej:Date
activa:Boolean
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
TPReloj
+leerHora():String
+ejecutarTarea()
TPAviso
TPEjecucion
msg:String
cmd:String
+leerMsg():String
+ejecutarTarea()
+leerCmd():String
+ejecutarTarea()
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojextendsTareaPeriodica{
publicTPReloj(){
super(60);
}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE);
}
publicvoidejecutarTarea(){
Calendarcal=newGregorianCalendar();
intmin=cal.get(Calendar.MINUTE);
if(min==0||min==30)
System.out.println("Hora:"+cal.get(Calendar.HOUR_OF_DAY)
+""+min);
}
}
Adicin,redefinicin
yanulacin
importjava.lang.Runtime;
importjava.io.IOException;
Programacinorientadaa
objetosenJava
publicclassTPEjecucionextendsTareaPeriodica{
Stringcmd;
publicTPEjecucion(StringaCmd,intaPeriodoSegs){
super(aPeriodoSegs);
cmd=aCmd;
}
StringleerCmd(){returncmd;}
publicvoidejecutarTarea(){
try{
Runtime.getRuntime().exec(cmd);
}
catch(IOExceptione){
System.out.println("Imposibleejecutarcomando:"
+cmd);
}
}
}
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicStringleerMsg(){returnmsg;}
publicvoidejecutarTarea(){
System.out.println("ATENCINAVISO:"+msg);
desactivar();
}
}
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
Cadatareaejecutaahorasufuncin,aunquelallamadaesaparentementelamisma
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
TPAvisotpa=newTPAviso(EstudiarProgramacinAvanzada!,60);
TPEjecuciontpe=newTPEjecucion(rm~/tmp/*,3600);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
while(!tpa.necesitaEjecucion())
System.println(Esperandoejecucindeaviso...);
tpa.ejecutarTarea();
while(!tpr.necesitaEjecucion())
System.println(Esperandoejecucindecomando...);
tpe.ejecutarTarea();
}
}
Despusdelaredefinicin,eneldescendientees
posiblellamaralaversinoriginaldelaoperacinenel
ascendientemediante:super.operacionRedefinida()
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
Otrousoposibledelapalabraclavefinalesimpedirla
redefinicindeunaoperacinenlassubclases
importjava.util.*;
publicclassTareaPeriodica{
intperiodoSegs;
DateultimaEj;
booleanactiva;
publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
publicTareaPeriodica(){this(1);}
finalpublicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}
finalpublicbooleannecesitaEjecucion(){
//Implementacindelaoperacin
}
publicvoidejecutarTarea(){
System.out.println("Ejecuciondetarea");
}
finalpublicvoidactivar(){activa=true;}
finalpublicvoiddesactivar(){activa=false;}
}
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
Laanulacinesunmecanismomenostil,ycon
menorsoporteporpartedeloslenguajesde
programacin
EnJavaesposibleimpedirelaccesoaunatributo
redeclarndoloenunasubclasecomoprivadoo
protegido,segnseaelniveldeproteccinquese
desee
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
//Impedirelaccesodesdeelexteriorylassubclases
//alatributoactiva
privatebooleanactiva;
publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
//Restodelaimplementacindelaclaseapartirdeaqu
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
Sinembargo,Javanopermiteredefinirunaoperacin
haciendosuniveldeaccesomsrestrictivo
Unasolucinparcialconsistiraenredefinirlacomo
vacaoincluyendouncdigoqueimpidasuutilizacin
publicclassTPAvisoextendsTareaPeriodica{
Stringmsg;
publicTPAviso(StringaMsg,intaPeriodoSegs){
super(aPeriodoSegs);
msg=aMsg;
}
publicvoidactivar(){}
publicvoiddesactivar(){
System.out.printl(Error:llamadaaoperacinprivada);
System.getRuntime().exit(1);
}
publicStringleerMsg(){returnmsg;}
publicvoidejecutarTarea(){
System.out.println("ATENCINAVISO:"+msg);
desactivar();
}
}
Adicin,redefinicin
yanulacin
Programacinorientadaa
objetosenJava
Proteccinyherencia
Hemosvistoanteriormentecomolosdistintosniveles
deproteccinlimitanelaccesoalosmiembrosdela
clasedesdeelexterior.Perocomoafectanestos
nivelesdeproteccinalosmiembrosheredados?
Miembrospblicos.Sonaccesiblesdesdelosdescendientes,yseheredancomo
pblicos
Miembrosprivados.Nosonaccesiblesdesdelosdescendientes
Miembrosconaccesoaniveldepaquete.Sonaccesiblesdesdelosdescendientes
siempreycuandopertenezcanalmismopaquetequeelascendiente.Seheredan
conelmismoniveldeproteccin
Unnuevoniveldeproteccineseldemiembros
protegidos(protected).Unmiembroprotegidoes
accesiblenicamentedesdelosdescendientes
Proteccinyherencia
Programacinorientadaa
objetosenJava
Adems,unmiembroprotegidomantieneenlas
subclaseselniveldeaccesoprotegido
Ennuestroejemplo,losatributosdelaclaseTareaPeriodicasonaccesiblesdesde
TPReloj,TPEjecucionyTPAvisoporquealperteneceralmismopaquetesonamigas
ParapermitirelaccesoalosatributosdelaclaseTareaPeriodicanicamente
desdelosdescendientesesconvenientemarcarloscomoprotegidos
importjava.util.*;
publicclassTareaPeriodica{
protectedintperiodoSegs;
protectedDateultimaEj;
booleanactiva;
publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
//Restodeoperacionesdelaclaseapartirdeaqu
Proteccinyherencia
Programacinorientadaa
objetosenJava
Clasesabstractas
Existenclasesquerepresentanconceptostan
genricosquenotienesentidosuinstanciacinen
objetos
Ademsenestetipodeclasespuedeserimposibleo
intillaimplementacindeciertasoperaciones
Lautilidaddeestetipodeclasesestenlaaplicacin
deherenciaparaobtenerclasesquerepresentan
conceptosconcretosparalosquesquetienesentido
suinstanciacin
LaclaseTareaPeriodicaesunclaroejemplo:porssolanotieneutilidad,pero
simplificamucholaconstruccindelasotrastresclases.Dehecho,laoperacin
ejecutarTarea()enTareaPeriodicanotieneunaimplementacintil
Clasesabstractas
Programacinorientadaa
objetosenJava
Estasclasessedenominanclasesabstractasyeste
tipodeoperacionessinimplementacinposible,
operacionesabstractas
Lasoperacionesabstractasdebenserimplementadas
obligatoriamenteenalgunadelassubclasesparaque
laclasecorrespondienteseainstanciable
Unaclaseabstractapuedenotenerningunaoperacin
abstracta,perounaclasequecontengaalmenosuna
operacinabstractadebeserdeclaradacomoabstracta
EnJava,utilizandoladeclaracinabstractpodremos
establecerunaclaseounaoperacincomoabstracta
Clasesabstractas
Programacinorientadaa
objetosenJava
VamosadeclararlaclaseTareaPeriodicaysuoperacinejecutarTarea()como
abstractas
importjava.util.*;
abstractclassTareaPeriodica{
intperiodoSegs;
DateultimaEj;
booleanactiva;
publicTareaPeriodica(intaPeriodoSegs){
periodoSegs=aPeriodoSegs;
actualizarReloj();
activa=true;
}
publicTareaPeriodica(){this(1);}
publicvoidactualizarReloj(){
ultimaEj=newDate();//Horaactual
}
publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;
//Restodelaimplementacindeesta
//operacinaqu
}
abstractpublicvoidejecutarTarea();
publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activa=false;}
}
Clasesabstractas
Programacinorientadaa
objetosenJava
Javadevuelveahoraunerrorentiempodecompilacinsiseintentacrearunobjeto
delaclaseTareaPeriodica
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTareaPeriodica(5);
while(!tp.necesitaEjecucion())
System.println(Esperandoejecucindetareaperidica...);
tp.ejecutarTarea();
}
}
AppGestorTareas.java:XX:classTareaPeriodicaisanabstractclass;cannotbeinstantiated
TareaPeriodicatp=newTareaPeriodica();
^
1error
Laabstraccindeunaclasesepropagaporla
jerarquadeherenciahastaquetodaslasoperaciones
quedanimplementadas
Clasesabstractas
Programacinorientadaa
objetosenJava
Laideadeclaseabstracta,llevadaalextremo,nos
llevaenJavaalasinterfaces.Unainterfazessimilara
unaclasetotalmenteabstracta:
Todaslasoperacionesdelainterfazsonimplcitamenteabstractas,esdecir,
carecendeimplementacin
Unainterfaznopuedeconteneratributos
Lasinterfacessirvenparaespecificarlasoperaciones
queobligatoriamentedebenimplementarunaseriede
clases
Laimplementacindeunainterfaznoserealiza
medianteherencia(extends)sinomedianteimplements.
Noobstante,elcomportamientoessimilaraldela
herencia,aunquemssencillo
Clasesabstractas
Programacinorientadaa
objetosenJava
Laideadeclaseimplementaunainterfaz,esta
implementacindebesercompleta,esdecir,detodas
lasoperacionesdelainterfaz
PodemostransformarTareaPeriodicaenunainterfaz,deformaqueespecifiquelo
quetienequeimplementarcualquierclasequerepresenteunatareaperidica.Este
enfoqueproporcionamayorlibertadalahoradedisearlasotrasclases
<<interfaz>>
TareaPeriodica
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
TPReloj
+leerHora():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
TPEjecucion
TPAviso
cmd:String
msg:String
+leerCmd():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
+leerMsg():String
+necesitaEjecucion():Boolean
+actualizarReloj()
+ejecutarTarea()
+activar()
+desactivar()
Clasesabstractas
Programacinorientadaa
objetosenJava
LainterfazTareaPeriodicaylaclaseTPRelojtendranahoraelsiguienteaspecto.
Lasotrasclasestendranimplementacionessimilares
publicinterfaceTareaPeriodica{
booleannecesitaEjecucion();
voidejecutarTarea();
voidactivar();
voiddesactivar();
}
importjava.util.Calendar;
importjava.util.GregorianCalendar;
publicclassTPRelojimplementsTareaPeriodica{
DateultEjecucion;
booleanactiva;
publicTPReloj(){activa=true;ultEjecucion=newDate()}
publicvoidejecutarTarea(){
Calendarcal=newGregorianCalendar();
intmin=cal.get(Calendar.MINUTE);
System.out.println("Hora:"+cal.get(Calendar.HOUR_OF_DAY)
+""+min);
ultEjecucion=cal.getTime();
}
Clasesabstractas
Programacinorientadaa
objetosenJava
publicbooleannecesitaEjecucion(){
if(!activa)
returnfalse;
CalendarcalProximaEj=newGregorianCalendar();
CalendarcalUltEjecucion=newGregorianCalendar();
calUltEjecucion.setTime(ultEjecucion);
CalendarcalAhora=newGregorianCalendar();
if(calAhora.equal(calUltEjecucion))
returnfalse;
intmin=calAhora.get(Calendar.MINUTE);
if(min==00||min==30)
returntrue;
returnfalse;
}
publicvoidactivar(){activa=true;}
publicvoiddesactivar(){activar=false;}
publicStringleerHora(){
Calendarcal=newGregorianCalendar();
returncal.get(Calendar.HOUR_OF_DAY)+":"+
cal.get(Calendar.MINUTE);
}
}
Clasesabstractas
Programacinorientadaa
objetosenJava
Unaclasepuedeimplementarmsdeunainterfaz
Unainterfazpuedeheredardeotrainterfaz
Cuandoutilizarunainterfazenlugardeunaclase
abstracta?
Porsusencillezserecomiendautilizarinterfacessiemprequeseaposible
Silaclasedebeincorporaratributos,oresultainteresantelaimplementacinde
algunadesusoperaciones,entoncesdeclararlacomoabstracta
EnlabibliotecadeclasesdeJavasehaceunuso
intensivodelasinterfacesparacaracterizarlasclases.
Algunosejemplos:
Paraqueunobjetopuedaserguardadoenunficherolaclasedebeimplementarla
interfazSerializable
Paraqueunobjetoseaduplicable,suclasedebeimplementarCloneable
Paraqueunobjetoseaordenable,suclasedebeimplementarComparable
Clasesabstractas
Programacinorientadaa
objetosenJava
Herenciamltiple
Consisteenlaposibilidaddequeunaclasetenga
variosascendientesdirectos
Puedesurgirdemanerarelativamentefrecuentey
naturalduranteeldiseo
FiguraGeometrica
Lista
almacena
*
Punto
Poligono
FicheroLectura
FicheroEscritura
FicheroLecturaEscritura
Imagen
EnlaceURL
ImagenSensible
Herenciamltiple
Programacinorientadaa
objetosenJava
Tieneclaramenteaspectospositivos
Surgedemaneranaturalaldescribirlaestructuradeunsistema
Proporcionamuchaflexibilidadalahoradeconstruirclasesnuevas
Perotambinaspectosnegativos
Complicaeldiseo.Lajerarquadeclasesdejadesertaljerarquapara
pasaraserunared
Provocaproblemasdeeficiencia.Lallamadaaunaoperacinheredada
implicalabsquedapormltiplescaminos
Ambigedad:dosatributosuoperacionesconelmismonombrepueden
llegaraunaclasepordoscaminosdistintos
Herenciarepetida:enunaestructuraconformaderombo,unatributou
operacinpuedellegaraunaclasepordoscaminosdistintos
D
A
atributoX
atributoX
atributoX
C
C
Herenciamltiple
Programacinorientadaa
objetosenJava
LaapuestadeloscreadoresdeJavaesclara:no
permitirlaherenciamltiple,porlasrazonesexpuestas
anteriormente
Avecesesposiblesustituirlaherenciamltiplepor
unacombinacinherencia/composicin,aunqueel
resultadonopuedeconsiderarseequivalente
FiguraGeometrica
Poligono
contiene
1
Lista
almacena
Segmento
listaPuntos():Lista
FiguraGeometrica
Poligono
contiene
1
aadir(s:Segmento)
Lista
aadir(s:Segmento)
borrarPrim()
borrarUlt()
almacena
*
Segmento
Herenciamltiple
Programacinorientadaa
objetosenJava
Adems,Javasquepermitelaimplementacinde
unaovariasinterfacesademsdelaherencia,loque
puedeconsiderarseunaformarestringidadeherencia
mltiple
Unaclasepuedeheredardeotraeimplementarunao
variasinterfacessinqueaparezcanlosproblemas
asociadosconlaherenciamltiple
<<interfaz>>
FiguraGeometrica
Lista
almacena
*
Segmento
Poligono
Herenciamltiple
Programacinorientadaa
objetosenJava
Polimorfismo
Sondosmecanismosrelacionadosqueotorganala
OOPunagranpotenciafrenteaotrosparadigmasde
programacin
nicamentetienensentidoporlaexistenciadela
herencia
Elpolimorfismo(oupcasting)consisteenlaposibilidad
dequeunareferenciaaobjetosdeunaclasepueda
conectarsetambinconobjetosdedescendientesde
sta
Ara=newA();//Asignacinordinaria
Brb=ra;//Asignacinpolimorfa
objeto:A
rb:B
ra:A
Brb=newA();//Asignacionpolimorfa
Polimorfismo
Programacinorientadaa
objetosenJava
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
TareaPeriodicatp;
tp=tpr;
tp.desactivar();
tp=tpa;
tp.desactivar();
tp=tpe;
tp.desactivar();
}
}
Elsentidodelpolimorfismoesrealizarunageneraliza
cin,olvidarlosdetallesconcretosdeunoovarios
objetosdedistintasclasesybuscarunpuntocomna
todosellosenunancestro
Polimorfismo
Programacinorientadaa
objetosenJava
Lamayoradelasveces,lasconexionespolimorfasse
realizandemaneraimplcitaenelpasodeargumentos
aunaoperacin.Deestamaneraesposibleescribir
operacionespolimorfasquerecibanobjetosde
mltiplesclases
publicclassAppGestorTareas{
privatestaticvoidesperarEjecutar(TareaPeriodicatp)
{
while(!tp.necesitaEjecucion());
tp.ejecutarTarea();
}
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
esperarEjecutar(tpr);
esperarEjecutar(tpa);
esperarEjecutar(tpe);
}
}
Polimorfismo
Programacinorientadaa
objetosenJava
Otraaplicacinmuytileslaconstruccinde
estructurasdedatosquepuedanmantenerobjetosde
distintasclases
VamosaimplementarunanuevaclaseGestorTareasquevaacontenerunalistade
tareasarealizar.LallamadaachequearEjecutar()realizarlacomprobaciny
ejecucindelastareasquelorequieran
importjava.lang.Exception;
classDemasiadasTareasextendsException{}
publicclassGestorTareas{
TareaPeriodica[]tareas;
intnTareas,maxTareas;
publicGestorTareas(intaMaxTareas){
nTareas=0;
maxTareas=aMaxTareas;
tareas=newTareaPeriodica[maxTareas];
}
//Sigue...
Polimorfismo
Programacinorientadaa
objetosenJava
//ContinuacindelaclaseGestorTareas
publicvoidnuevaTarea(TareaPeriodicatp)
throwsDemasiadasTareas{
if(nTareas==maxTareas)
thrownewDemasiadasTareas();
tareas[nTareas++]=tp;
}
publicvoidchequearEjecutar()
{
for(intt=0;t<nTareas;t++)
if(tareas[t].necesitaEjecucion())
tareas[t].ejecutarTarea();
}
}
importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
GestorTareasgt=newGestorTareas(10);
try{
gt.nuevaTarea(newTPReloj());
gt.nuevaTarea(newTPAviso(Hapasadounminuto,60));
gt.nuevaTarea(newTPEjecucion(/bin/sync,120));
}catch(DemasiadasTarease){
System.out.println(Mmmm....estonodeberiahaberpasado);
}
gt.chequearEjecutar();
}
}
Polimorfismo
Programacinorientadaa
objetosenJava
Perosiempredebequedarclaroquetraslaconexin
polimorfanicamentepodemosaccederalasopera
cionespertenecientesalaclaseasociadaalarefe
rencia.Elrestodeoperacionesdelobjetonoson
accesiblesatravsdeestareferencia
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TareaPeriodicatp;
tp=tpr;
tp.desactivar();//Ok
tp.leerHora()//Error!!
tpr.leerHora();//Ok
}
}
AppGestorTareas.java:XX:cannotresolvesymbol
symbol:methodleerHora()
location:classTareaPeriodica
tp.leerHora();
^
1error
Polimorfismo
Programacinorientadaa
objetosenJava
EnJava,unareferenciaaObjectpuedeserconectada
acualquierobjeto,puestoquecomosabemosesun
ancestrodetodaslasclases
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
Objecto;
o=tpr;
System.out.println(o.getClass().getName());
}
}
Adems,lasinterfacesimplementadasporunaclase
tambinpuedenserutilizadaspararealizarconexiones
polimorfas
Polimorfismo
Programacinorientadaa
objetosenJava
Ligaduradinmica
Entendemosporresolucindeunallamadaelproceso
porelcualsesustituyeunallamadaaunafuncinpor
unsaltoaladireccinquecontieneelcdigodeesta
funcin
Normalmente,laresolucindellamadasserealizaen
entiempodecompilacin,porqueresultamssencilloy
sobretodomseficiente.Cuandolaaplicacinseest
ejecutando,lasllamadasyaestnpreparadas.Este
enfoquesedenominaligaduraesttica
f()
CALL_f
Ligaduradinmica
Programacinorientadaa
objetosenJava
ElproblemaapareceenOOPcuandorealizamosuna
conexinpolimorfayllamamosaunaoperacin
redefinida
f()
f()
f()
Ar=??
r.f()
CALL_A_f?
CALL_B_f?
CALL_C_f?
Elcompiladornotieneinformacinpararesolverla
llamada.Pordefectoutilizaraeltipodelareferencia,y
portantogeneraraunallamadaaA.f()
Perolareferenciarpuedeapuntaraobjetosdelas
clasesA,BoC,condistintasversionesdef()
Ligaduradinmica
Programacinorientadaa
objetosenJava
Lasolucinconsisteenesperararesolverlallamada
altiempodeejecucin,cuandoseconocerealmente
losobjetosconectadosar,yculeslaversindef()
apropiada.Esteenfoquederesolucindellamadasse
denominaligaduradinmicayesmuchomslentay
complejaquelaesttica
Haytresenfoquesposiblesalahoradeescogerentre
ligaduraestticaodinmica:
Establecerlaligaduraestticapordefecto.Elprogramadorpuedeactivarla
ligaduradinmicaparaunafuncinconcretacuandolovenecesario(C++)
Utilizaruncompiladorinteligentequedecidelaligaduraestticaodinmicaen
funcindelempleoquesehacedecadafuncin(Eiffel)
Establecerlaligaduradinmicaparatodaslasfuncionesyevitarproblemasacosta
deeficienciaenlaejecucin(Smalltalk,Java)
Ligaduradinmica
Programacinorientadaa
objetosenJava
Portanto,laligaduradinmica,pordefectoenJava,
garantizasiemprelallamadaalaversincorrectade
cadafuncin,conindependenciadelusodeconexiones
polimorfasono
PortantoenJavalasllamadasalafuncinejecutarTarea()seresuelven
correctamente,apesarderealizarseatravsdeunareferenciaaTareaPeriodica
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TPRelojtpr=newTPReloj();
TPAvisotpa=newTPAviso(Hapasadounminuto,60);
TPEjecuciontpe=newTPEjecucion(/bin/sync,120);
TareaPeriodicatp;
tp=tpr;
tp.ejecutarTarea();//VersindeTPReloj
tp=tpa;
tp.ejecutarTarea();//VersindeTPAviso
tp=tpe;
tp.ejecutarTarea();//VersindeTPEjecucion
}
}
Ligaduradinmica
Programacinorientadaa
objetosenJava
Informacindeclasesentiempodeejecucin
Trasrealizarunaconexinpolimorfaesfrecuentela
necesidaddevolverarecuperarelobjetooriginal,para
accederasusoperacionespropias
Setratadelaoperacininversaalpolimorfismo
(upcasting),denominadadowncasting
Sielpolimorfismoimplicaunageneralizacin,el
downcastingimplicaunaespecializacin
Alcontrarioqueelupcasting,eldowncastingnopuede
realizarsedirectamentemedianteunaconexinconuna
referenciadelaclasedelobjeto
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
TrascrearunobjetodetipoTPRelojyconectarlomedianteunareferenciaa
TareaPeriodica,intentamosrecuperarnuevamenteunareferenciadetipoTPRelojal
objeto.Noesposibledemaneradirecta
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=tp;//downcasting?
}
}
AppGestorTareas.java:XX:incompatibletypes
found:TareaPeriodica
required:TPReloj
TPRelojtr=tp;
^
1error
Unsimplecastingpermiteforzarlaconexinala
referencia
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=(TPReloj)tp;//downcasting
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Unintentodecastingimposiblegeneraruna
excepcinClassCastExceptionentiempodeejecucin
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp=newTPReloj();//upcasting
TPRelojtr=(TPReloj)tp;//downcastingok
//Downcastingimposible:lanzaexcepcinClassCastException
TPAvisota=(TPAviso)tp;
}
}
ExceptioninThreadmainjava.lang.ClassCastException
atAppGestorTareas.main(AppGestorTareas.java:XX)
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Podemoscapturarestaexcepcinparadeterminarsiel
objetoapuntadoporlareferenciaesdeltipoesperadoo
no,realizandoaccionesdiferentesencadacaso
importjava.lang.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;
TPRelojtr;
//Posiblementeenalgnpuntolareferenciatphasidoconectada
//conunobjetodelaclaseTPReloj
...
try{
tr=(TPReloj)tp;
System.out.println(Lahoraactuales:+tr.leerHora());
}
catch(ClassCastExceptione){
System.out.println(Lareferenciatpnoapuntaaunobjeto
+delaclaseTPReloj);
}
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
importjava.lang.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte;
//tpesconectadaaalgnobjeto
...
try{
tr=(TPReloj)tp;
//Operarcontr
return;
}
catch(ClassCastExceptione){
//SinoesdetipoTPReloj,continuamosporaqu
}
try{
ta=(TPAviso)tp;
//Operarconta
return;
}
catch(ClassCastExceptione){
//SinoesdetipoTPAviso,continuamosporaqu
}
try{
te=(TPEjecucion)tp;
//Operarconte
return;
}
catch(ClassCastExceptione){
//SitampocoesdetipoTPEjecucinEntoncesdequetipoes?
System.out.println(Error:objetodeclasedesconocida);
}
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Muchomscmodoesutilizarinstanceofpara
determinasielobjetoesdelaclaseesperadaantesde
realizarelcasting
importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte;
//tpesconectadaaalgnobjeto
...
if(tpinstanceofTPReloj){
tr=(TPReloj)tp;
//Operarcontr
}
else
if(tpinstanceofTPAviso){
ta=(TPAviso)tp;
//Operarconta
}
else
if(tpinstanceofTPEjecucion){
te=(TPEjecucion)tp;
//Operarconte
}
else
System.out.println(Error:objetodeclasedesconocida);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
LaoperacingetClass()deObjectdevuelveunobjeto
delaclaseClassquepermiteobtenerentiempode
ejecucingrancantidaddeinformacindelaclaseala
queperteneceelobjeto.Elatributoestticoclassdela
clasetambindevuelveunareferenciaaesteobjeto
importjava.lang.System;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
TareaPeriodicatp;
//tpesconectadaaalgnobjeto
...
Classc=tp.getClass();
System.out.println(Lareferenciatpapuntaaunobjetodelaclase:
+c.getName());
Classc=TareaPeriodica.class;
if(c.isInterface())
System.out.println(TareaPeriodicaesunaInterfaz);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
LaslibrerasdecontenedoresdeJava(java.util)
utilizanelpolimorfismoparaconseguirgenericidad,
trabajandosiempreconObject
Alahoraderecuperarlosobjetosalmacenados,es
necesarioutilizardowncastingparaconectarconuna
referenciadelaclaseapropiada
importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedListl=newLinkedList;
//Aadirelementos
l.add(newString(Jan));
l.add(Granada);
//Recuperarelprimerelemento
Strings=(String)l.get(0);
System.out.println(s);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Apartirdelaversin5,Javahaincorporadosimilaral
utilizadoporlostemplatesdeC++paraespecificarel
tipodeloselementosdelcontenedor
Laventajaesquelareferenciadevueltaes
directamentedeltipoespecificadoenlacreacindel
contenedor
importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedList<String>l=newLinkedList<String>;
//Aadirelementos
l.add(newString(Jan));
l.add(Granada);
//Yanoesnecesarioeldowncasting
Strings=l.get(0);
System.out.println(s);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Otroinconvenientedelusodelpolimorfismoparala
implementacindeloscontenedoresesquelostipos
simples(int,char,etc.)nopuedenalmacenarse
directamente,alnoserclasesdeobjetos
Parasolucionarlo,Javaincorporaunaclasewrapper
paracadatiposimple:(int>Integer,char>Character,
etc.)
importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedListl=newLinkedList;
//Aadirelementos
l.add(newInteger(5));
l.add(newInteger(3));
//Recuperarelprimerelemento
inti=((Integer)l.get(0)).intValue();
System.out.println(i);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
Nuevamente,apartirdelaversin5,esteproblemase
haeliminadoconelautoboxingdetipossimples
Esdecir,Javatransformauntiposimpleensuclase
wrappercuandoesnecesariodemaneraautomtica
EsalgosimilaralaconstruccinautomticadeString
apartirdearraysdecaractresqueyaconocemos
importjava.util.*;
publicclassAppGestorTareas{
publicstaticvoidmain(String[]args){
LinkedList<Integer>l=newLinkedList<Integer>;
//Aadirelementos.LaconversinaIntegeres
//automtica
l.add(5);
l.add(3);
//Recuperarelprimerelemento.Laconversina
//intesautomtica
inti=l.get(0);
System.out.println(i);
}
}
Informacinde
clasesentiempode
ejecucin
Programacinorientadaa
objetosenJava
OtrostemasdeintersenJava
Entrada/Salida.LalibreradeclasesdeJavadispone
degrancantidaddeclasesparalagestintransparente
deE/S.Estasclasespuedencombinarseparacrear
flujosdedatosespecializados
E/SBinaria(streams):
LasclasesFileInputStreamyFileOutputStreampermiteabrirstreamsdeE/S
secuencialaficherosendisco.LaclaseRandomAccessFilepermiteleeryescribir
informacinaunficherodeformaaleatoria
LasclaseBufferedInputStreamyBufferedOutputStreampermiteleeryescribir
informacindeuninput/outputstream,utilizandounbufferintermedioparaacelerar
lasoperaciones
LasclasesDataInputStreamyDataOutputStreampermiteleeryescribirtipos
simplesenuninput/outputstream
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Ejemplo.Lecturayescriturabsicasenunfichero:
importjava.io.*;
publicclassESBinaria{
publicstaticvoidmain(String[]args){
DataOutputStreamds=
newDataOutputStream(
newBufferedOutputStream(
newFileOutputStream(datos)));
ds.writeInt(2);
ds.writeFloat(4.5);
ds.writeChars(Hola);
ds.close();
ds=newDataInputStream(
newBufferedInputStream(
newFileInputStream(datos)));
intk=ds.readInt();
System.out.println(k);
ds.close();
}
}
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
E/Sdecaracteres(readers)
LasclasesFileReaderyFileWriterpermiteabrirreaders/writersdeacceso
secuencialaficherosendisco
LasclasesBufferedReaderyBufferedWriterpermiteleeryescribirinformacin
utilizandounbufferintermedioparaacelerarlasoperaciones.Posibilitanel
leer/escribirlineascompletas
LasclasesInputStreamReaderyOutputStreamWriterpermitenconvertirunstream
enunreader/writer
LaclaseespecializadaPrintWriterpermiteescribirdirectamentecualquiertipode
datoenunwriter.SuusoesmscmodoqueeldeunBufferedWriter
LaclaseespecializadaScannerpermiteleerdemanerasencillacualquiertipo
simpledeunficherodetexto.Suusoesmscomodoquemediante
BufferedReader
VerelapartadoI/O:ReadingandWritingdeltutorial
Javaylaspginasdelasclasescitadasenelmanual
dereferenciaparamsinformacin
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Ejemplo.EscrituradeunficheromedianteBufferedWriteryPrintWriter:
importjava.io.*;
publicclassESTexto{
publicstaticvoidmain(String[]args){
try{
BufferedWriterbw=newBufferedWriter(newFileWriter(datos.txt));
bw.write(Hola);
bw.writeLine();
bw.write(newInteger(3).toString());
bw.writeLine();
bw.write(newFloat(10.3).toString());
bw.close();
PrintWriterpw=newPrintWriter(datos.txt);
pw.println(Hola);
pw.println(3);
pw.println(10.3);
pw.close();
}
catch(IOExceptione){
System.out.println(ErrordeE/S);
}
}
}
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Haydosmtodosdelectura:
Elprimerousalaoperacinparse()delasclaseswrapperdelostiposbsicos
Elsegundo,msflexibleysencillo,utilizalaclaseScanner
importjava.io.*;
importjava.util.Scanner;
publicclassESTexto{
publicstaticvoidmain(String[]args){
try{
BufferedReaderbr=newBufferedReader(
newFileReader(datos.txt));
Strings=br.readLine();
intk=Integer.parseInt(br.readLine());
floatp=Float.parseFloat(br.readLine());
br.close();
Scannersc=newScanner(newFile(datos.txt));
s=sc.nextLine();
k=sc.nextInt();
p=sc.nextFloat();
sc.close();
}
catch(IOExceptione){
System.out.println(ErrordeE/S);
}
}
}
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Serializacin.Unadelascaractersticasmspotentes
deJavaeslaposibilidaddeserializarunobjeto,es
decir,convertirloenunasecuenciadebytesyenviarlo
aunficheroendisco,porunsocketaotroordenadora
travsdelared,etc.Elprocesoseraelsiguiente:
DeclararlaimplementacindelainterfazSerializableenlaclasequedeseemos
serializar.Setratadeunainterfazvaca,porloquenohayoperacionesque
implementar
ParaserializarelobjetocrearamosunstreamObjectOutputStreamyescribiramos
elobjetomediantelaoperacinwriteObject()
ParadeserializarelobjetocrearamosunstreamObjectInputStream,leeramosel
objetomediantereadObject()yrealizaramosuncastingalaclasedelobjeto
VerelapartadoObjectSerializationdeltutorialJava
paramsinformacin
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
VamosamodificarahoraelconstructordelaclaseCuentaylaoperacinsalvar()
paraqueseancapacesdecargarysalvarelhistoricodemovimientos.Lacapacidad
deserializacindeJavapermitesalvarlalistaenlazadadeungolpe
importjava.io.*;
importjava.util.*;
//EsnecesarioquetantolasclasesClientecomoMovimientoimplementenlainterfaz
//Serializableparaquelosobjetospuedanserescritosendisco
classMovimientoimplementsSerializable{
Datefecha;
chartipo;
floatimporte;
floatsaldo;
publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){
fecha=aFecha;
tipo=aTipo;
importe=aImporte;
saldo=aSaldo;
}
}
publicclassCuenta{
longnumero;
Clientetitular;
privatefloatsaldo;
floatinteresAnual;
LinkedListmovimientos;
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){
numero=aNumero;
titular=aTitular;
saldo=0;
interesAnual=aInteresAnual;
movimientos=newLinkedList();
}
Cuenta(longaNumero)throwsFileNotFoundException,
IOException,ClassNotFoundException{
ObjectInputStreamois=newObjectInputStream(newFileInputStream(aNumero+".cnt"));
numero=ois.readLong();
titular=(Cliente)ois.readObject();
saldo=ois.readFloat();
interesAnual=ois.readFloat();
movimientos=(LinkedList)ois.readObject();
ois.close();
}
voidsalvar()throwsFileNotFoundException,IOException{
ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream(numero+".cnt"));
oos.writeLong(numero);
oos.writeObject(titular);
oos.writeFloat(saldo);
oos.writeFloat(interesAnual);
oos.writeObject(movimientos);
oos.close();
}
//RestodeoperacionesdelaclaseCuentaapartirdeaqu
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Multitarea.Esposibleimplementarunaovariastareas
queseejecutenenvariashebrasdeejecucinen
paralelo,delasiguientemanera
ConstruirunaclasequerepresentelatareayherededelaclaseJavaThread
Redefiniendolaoperacinrun()deThreadpodremosintroducirelcdigoque
deseamosejecutarenlahebra
Paraarrancarlanuevahebrabastaconcrearunobjetodelaclaseyejecutarla
operacinstart()
Sisedeseapararlahebraduranteuntiempodeterminado,puedeutilizarsela
operacinsleep(intsegs)
Latareafinalizacuandoseelhilodeejecucinllegadeformanaturalalfinaldela
operacinrun()
VerelapartadoThreads:doingtwoormoretasksat
oncedelTutorialJavaparamsinformacin
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Ejemplo:ungestordetareasquefuncionaenparaleloconelrestodelaaplicacin,
realizandolacomprobacinperidicadelastareasquerequierenejecucin
importjava.lang.Exception;
classDemasiadasTareasextendsException{}
publicclassGestorTareasextendsThread{
TareaPeriodica[]tareas;
intnTareas,maxTareas;
booleanterminar;
publicGestorTareas(intaMaxTareas){
super("GestorTareas");
terminar=false;
nTareas=0;
maxTareas=aMaxTareas;
tareas=newTareaPeriodica[maxTareas];
}
publicvoidnuevaTarea(TareaPeriodicatp)throwsDemasiadasTareas{
if(nTareas==maxTareas)
thrownewDemasiadasTareas();
tareas[nTareas++]=tp;
}
//Sigue...
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Laoperacinterminar()vaapermitirforzarlafinalizacindelgestordetareas
//ContinualaclaseGestorTareas
publicvoidrun()
{
System.out.println("Gestordetareasenfuncionamiento");
while(!terminar){
for(intt=0;t<nTareas;t++)
if(tareas[t].necesitaEjecucion())
tareas[t].ejecutarTarea();
//Esperarunsegundoantesdevolveracomprobar
try{
sleep(1);
}
catch(InterruptedExceptione){};
}
System.out.println("Finalizandogestordetareas");
}
voidterminar(){terminar=true;}
}
Otrostemasde
intersenJava
Programacinorientadaa
objetosenJava
Estaaplicacincontaracondoshilosdeejecucinenparalelo,unoprincipalyotro
asociadoalgestordetareas
publicclassAppGestorTareas{
publicAppGestorTareas(){}
publicstaticvoidmain(String[]args){
GestorTareasgt=newGestorTareas(10);
try{
gt.nuevaTarea(newTPReloj());
gt.nuevaTarea(newTPAviso("Hapasado5segundos",5));
}catch(DemasiadasTareasdt){
System.out.println("Mmmm....estonodeberahaberpasado");
}
gt.start();
System.out.println("Hilodeejecucinprincipal");
System.out.println("Pulsaunateclaparaterminar");
try{
System.in.read();
}
catch(IOExceptione){}
System.out.println("Finaldeaplicacin");
gt.terminar();
}
}
Otrostemasde
intersenJava