Está en la página 1de 127

Programacinorientadaa objetosenJava

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

Programacinorientadaa objetosenJava

Clasesdeobjetos
Lasclasesdeobjetosrepresentanconceptoso entidadessignificativosenunproblemadeterminado. Unaclasedescribelascaractersticascomunesdeun conjuntodeobjetos,mediantedoselementos:

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


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

Atributos

Operaciones

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:
classCuenta{ longnumero; Stringtitular; floatsaldo; floatinteresAnual; voidingreso(floatcantidad){} voidreintegro(floatcantidad){} voidingresoInteresMes(){} booleanenRojos(){} floatleerSaldo(){} }

Atributos

Operaciones

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

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

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

Programacinorientadaa objetosenJava

Losmiembrosnoetiquetadossonaccesiblesporparte declasesamigas.EnC++yotroslenguajesOOlas clasesamigasaunadadapuedenindicarse explcitamente EnJavaseconsideranamigastodasaquellasque formanpartedelmismopaquete

Unficherofuentejavaformaensunpaqueteyportantotodaslasclasesincluidas enlsonamigas Lasclasesincluidasenvariosficherosfuentepuedenagruparseenunnico paqueteindicandoelnombredepaquetealprincipiodecadaficheromedianteel indicadorpackage


packageprueba; classA{ ... } classB{ ... } packageprueba; classC{ ... } 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 Creacindeobjetos

*VaseelapartadoCharactersandStringsdeltutorialdeJavadeSunparamsinformacin

Programacinorientadaa objetosenJava

Sielarrayesdereferenciasaobjetos,habrquecrear ademscadaunodelosobjetosreferenciadospor separado

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

Ladestruccindelosobjetosserealizademanera automticacuandoelrecolectordebasuradetectaque elobjetonoestsiendousado,esdecir,noest conectadoaningunareferencia

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

Creacindeobjetos

Programacinorientadaa objetosenJava

Trabajandoconobjetos
TrabajarconunobjetoJavaessimilaraC++,aunque lasreferenciaspermitenunusomuchomssencillo

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

Trabajandocon objetos

Programacinorientadaa objetosenJava

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

Programacinorientadaa objetosenJava

Naturalmenteelcompiladorproducirunerrorante cualquieraccesoilegalaunmiembrodelaclase

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

Elaccesoaunmiembroestticoserealizautilizando elnombredelaclaseenlugardeunobjeto

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


Trabajandocon objetos

Programacinorientadaa objetosenJava

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

*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
* 1

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; Cliente(StringaNombre,StringaApellidos,StringaDireccion, StringaLocalidad,DateaFNacimiento){ nombre=aNombre; apellidos=aApellidos; direccion=aDireccion; localidad=aLocalidad; fNacimiento=aFNacimiento; } StringnombreCompleto(){returnnombre++apellidos;} StringdireccionCompleta(){returndireccion+,+localidad;} }

Programacinorientadaa objetosenJava

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 formadopor
2 *

Segmento

Departamento

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
* 1

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

registra

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

Relacionesentre objetos

Programacinorientadaa objetosenJava

Lascomposicionestienenunaimplementacinsimilar alasasociaciones,conladiferenciadequeelobjeto principalrealizarenalgnmomentolaconstruccinde losobjetoscompuestos

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

Relacionesentre objetos

Programacinorientadaa objetosenJava

publicclassCuenta{ privatelongnumero; privateClientetitular; privatefloatsaldo; privatefloatinteresAnual; privateLinkedListmovimientos;//Listademovimientos //Constructorgeneral publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){ numero=aNumero;titular=aTitular;saldo=0;interesAnual=aInteresAnual; movimientos=newLinkedList(); } //Nuevaimplementacindeingresoyreintegro publicvoidingreso(floatcantidad){ movimientos.add(newMovimiento(newDate(),'I',cantidad,saldo+=cantidad)); } publicvoidreintegro(floatcantidad){ movimientos.add(newMovimiento(newDate(),'R',cantidad,saldo=cantidad)); } publicvoidingresoInteresMes(){ingreso(interesAnual*saldo/1200);} //RestodeoperacionesdelaclaseCuentaapartirdeaqu

Nota:tambinseranecesariomodificarelotroconstructorylaoperacinsalvarparatenerencuentalalistademovimientos alahoradeleer/escribirlainformacindelaCuentaendisco

Relacionesentre objetos

Programacinorientadaa objetosenJava

Clasesanidadaseinteriores
JavayalgunosotroslenguajesOOPpermitenla definicindeunaclasedeobjetosdentrodeotra,con unadobleutilidad:

Organizarmejorelcdigo.Empaquetarenunaclaseprincipalotrasquenotienen utilidadosentidofueradelcontextodesta Evitarcolisionesdenombres.Laclaseprincipaldefineunespaciodenombresalque pertenecenlasanidadas

Aligualquecualquierotromiembrodeunaclase,una claseanidadapuedeserestticaonoestticayutilizar losnivelesdeproteccinpublic,privateyprotected Eltipodeclaseanidamientomssencilloesaquelen quelaclasecontenidasedeclaracomoesttica

Clasesanidadase interiores

Programacinorientadaa objetosenJava

Desdeelpuntodevistadelaorganizacindelcdigo,tendramuchomssentido introducirlaclaseMovimientoenelinteriordeCuenta.Alserdeclaradacomoprivada, seimpedirasuutilizacindesdeelexterior


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

Programacinorientadaa objetosenJava

Cuandolaclaseanidadanoesesttica,sedenomina claseinteriorytienecaractersticasespeciales:

Puedensercreadasnicamentedentrodelaclasecontinente Tieneaccesocompletoydirectoatodoslosatributosyoperacionesdelobjetoque realizasucreacin

Losobjetosdelaclaseinteriorquedanligados permanentementealobjetoconcretodelaclase continentequerealizsucreacin Nodebeconfundirseesteelementoconlarelacinde composicin,aunqueenmuchoscasosesposible utilizarclasesinterioresparalaimplementacindeeste tipoderelaciones

Clasesanidadase interiores

Programacinorientadaa objetosenJava

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

Clasesanidadase interiores

Programacinorientadaa objetosenJava

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

Clasesanidadase interiores

Programacinorientadaa objetosenJava

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

Autoreferencias

Programacinorientadaa objetosenJava

LallamadaalaoperaciningresodesdeingresoInteresMes()puederealizarse utilizandothiscomoreferenciadelobjetosobreelqueseinvocalaoperacin
publicclassCuenta{ privatelongnumero; privateClientetitular; privatefloatsaldo,interesAnual; publicvoidingresoInteresMes(){this.ingreso(interesAnual*saldo/1200);} //RestodelasoperacionesdelaclaseCuenta

Enesteejemplo,elusodethisesrealmentetil.Nospermiteimplementarla operacintransferirDesde()llamandoaunaoperacintransferirHasta(),previamente implementada


publicclassCuenta{ privatelongnumero; privateClientetitular; privatefloatsaldo,interesAnual; publicvoidtransferirHasta(Cuentac,floatcant){ reintegro(cant);c.ingreso(cant); } publicvoidtransferirDesde(Cuentac,floatcant){ c.transferirHasta(this,cant); } //RestodelasoperacionesdelaclaseCuenta

Autoreferencias

Programacinorientadaa objetosenJava

OtrautilidaddethisenJavaesrealizarunallamadaa unconstructordesdeotroconstructor

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

Peroatencin:unconstructornoesunaoperacin ordinaria.nicamentepuedellamarseaunconstructor desdeotroconstructorydebeserlaprimerainstruccin dentrodelaimplementacin

Autoreferencias

Programacinorientadaa objetosenJava

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

Aplicaciones orientadasaobjetos

Programacinorientadaa objetosenJava

EnunlenguajeorientadoaobjetospurocomoJava estaclasedeaplicacinesobligatoria. LamquinavirtualJavaseencargadeinstanciaresta claseyllamaraunaoperacinespecialconnombre main.Laexistenciadeestaoperacinespecialeslo quecaracterizaalaclasedeaplicacin

Laclasedeaplicacindebeserpblicaynotenerningnconstructoroun constructorpordefecto Almenosdebeimplementarlaoperacinmain,conlasiguientedeclaracin:public staticmain(String[]args)


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

Programacinorientadaa objetosenJava

Alahoradeejecutarlaaplicacin,deberindicarse estaclasealamquinavirtualJava

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


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

Lamquinavirtualjava producirunerrorsise lepasaunaclasesin laoperacinmain

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 vencimiento:Date

PlanPensiones 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 buffer[nelem]:Elemento redimensionar(t:Integer)

Lista cabecera:Nodo insertar(e:Elemento,pos:Integer) insertaPrin(e:Elemento) insertarFinal(e:Elemento)

TablaHash tabla[nelem]: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 msg:String

TPEjecucion cmd:String +leerCmd():String

+leerHora():String +leerMsg():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; } publicStringleerMsg(){returnmsg;} }

Programacinorientadaa objetosenJava

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(...) B super(...) C D super(...) super(...)

Herencia

Programacinorientadaa objetosenJava

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

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


Herencia

Programacinorientadaa objetosenJava

Adicin,redefinicinyanulacin
Laherenciaensnoserataninteresantesinofuera porlaposibilidaddeadaptareneldescendientelos miembrosheredados

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

Notodosloslenguajesorientadosaobjetossoportan estascaractersticas,enespeciallaanulacin

Adicin,redefinicin yanulacin

Programacinorientadaa objetosenJava

LaredefinicinserealizaenJavaylamayoradelos lenguajesOOdefiniendonuevamentelaoperacin(con losmismosargumentos)eneldescendiente

LasclasesdescendientesTPReloj,TPEjecucionyTPAvisonoestnoperativas todavaporquelaimplementacindeejecutarTarea()quecontieneneslaheredadade TareaPeriodica,quenohacenadaenparticular Esprecisoredefinirestaoperacinencadaunadelassubclasesparaquerealicen lastareascorrespondientes


TareaPeriodica periodoSegs:Integer ultimaej:Date activa:Boolean +necesitaEjecucion():Boolean +actualizarReloj() +ejecutarTarea() +activar() +desactivar()

TPReloj

TPAviso msg:String

TPEjecucion cmd:String +leerCmd():String +ejecutarTarea()

+leerHora():String +ejecutarTarea()

+leerMsg():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; 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(); } }

Programacinorientadaa objetosenJava

Adicin,redefinicin yanulacin

Programacinorientadaa objetosenJava

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

Despusdelaredefinicin,eneldescendientees posiblellamaralaversinoriginaldelaoperacinenel ascendientemediante:super.operacionRedefinida()

Adicin,redefinicin yanulacin

Programacinorientadaa objetosenJava

Otrousoposibledelapalabraclavefinalesimpedirla redefinicindeunaoperacinenlassubclases

importjava.util.*; publicclassTareaPeriodica{ intperiodoSegs; DateultimaEj; booleanactiva; publicTareaPeriodica(intaPeriodoSegs){ periodoSegs=aPeriodoSegs; actualizarReloj(); activa=true; } publicTareaPeriodica(){this(1);} finalpublicvoidactualizarReloj(){ ultimaEj=newDate();//Horaactual } finalpublicbooleannecesitaEjecucion(){ //Implementacindelaoperacin } publicvoidejecutarTarea(){ System.out.println("Ejecuciondetarea"); } finalpublicvoidactivar(){activa=true;} finalpublicvoiddesactivar(){activa=false;} }

Adicin,redefinicin yanulacin

Programacinorientadaa objetosenJava

Laanulacinesunmecanismomenostil,ycon menorsoporteporpartedeloslenguajesde programacin EnJavaesposibleimpedirelaccesoaunatributo redeclarndoloenunasubclasecomoprivadoo protegido,segnseaelniveldeproteccinquese desee

publicclassTPAvisoextendsTareaPeriodica{ Stringmsg; //Impedirelaccesodesdeelexteriorylassubclases //alatributoactiva privatebooleanactiva; publicTPAviso(StringaMsg,intaPeriodoSegs){ super(aPeriodoSegs); msg=aMsg; } //Restodelaimplementacindelaclaseapartirdeaqu


Adicin,redefinicin yanulacin

Programacinorientadaa objetosenJava

Sinembargo,Javanopermiteredefinirunaoperacin haciendosuniveldeaccesomsrestrictivo Unasolucinparcialconsistiraenredefinirlacomo vacaoincluyendouncdigoqueimpidasuutilizacin

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

Programacinorientadaa objetosenJava

Proteccinyherencia
Hemosvistoanteriormentecomolosdistintosniveles deproteccinlimitanelaccesoalosmiembrosdela clasedesdeelexterior.Perocomoafectanestos nivelesdeproteccinalosmiembrosheredados?

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

Unnuevoniveldeproteccineseldemiembros protegidos(protected).Unmiembroprotegidoes accesiblenicamentedesdelosdescendientes

Proteccinyherencia

Programacinorientadaa objetosenJava

Adems,unmiembroprotegidomantieneenlas subclaseselniveldeaccesoprotegido

Ennuestroejemplo,losatributosdelaclaseTareaPeriodicasonaccesiblesdesde TPReloj,TPEjecucionyTPAvisoporquealperteneceralmismopaquetesonamigas ParapermitirelaccesoalosatributosdelaclaseTareaPeriodicanicamente desdelosdescendientesesconvenientemarcarloscomoprotegidos


importjava.util.*; publicclassTareaPeriodica{ protectedintperiodoSegs; protectedDateultimaEj; booleanactiva; publicTareaPeriodica(intaPeriodoSegs){ periodoSegs=aPeriodoSegs; actualizarReloj(); activa=true; } //Restodeoperacionesdelaclaseapartirdeaqu

Proteccinyherencia

Programacinorientadaa objetosenJava

Clasesabstractas
Existenclasesquerepresentanconceptostan genricosquenotienesentidosuinstanciacinen objetos Ademsenestetipodeclasespuedeserimposibleo intillaimplementacindeciertasoperaciones Lautilidaddeestetipodeclasesestenlaaplicacin deherenciaparaobtenerclasesquerepresentan conceptosconcretosparalosquesquetienesentido suinstanciacin

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


Clasesabstractas

Programacinorientadaa objetosenJava

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

Clasesabstractas

Programacinorientadaa objetosenJava

VamosadeclararlaclaseTareaPeriodicaysuoperacinejecutarTarea()como abstractas
importjava.util.*; abstractclassTareaPeriodica{ intperiodoSegs; DateultimaEj; booleanactiva; publicTareaPeriodica(intaPeriodoSegs){ periodoSegs=aPeriodoSegs; actualizarReloj(); activa=true; } publicTareaPeriodica(){this(1);} publicvoidactualizarReloj(){ ultimaEj=newDate();//Horaactual } publicbooleannecesitaEjecucion(){ if(!activa) returnfalse; //Restodelaimplementacindeesta //operacinaqu } abstractpublicvoidejecutarTarea(); publicvoidactivar(){activa=true;} publicvoiddesactivar(){activa=false;} } Clasesabstractas

Programacinorientadaa objetosenJava

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

Laabstraccindeunaclasesepropagaporla jerarquadeherenciahastaquetodaslasoperaciones quedanimplementadas

Clasesabstractas

Programacinorientadaa objetosenJava

Laideadeclaseabstracta,llevadaalextremo,nos llevaenJavaalasinterfaces.Unainterfazessimilara unaclasetotalmenteabstracta:

Todaslasoperacionesdelainterfazsonimplcitamenteabstractas,esdecir, carecendeimplementacin Unainterfaznopuedeconteneratributos

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

Clasesabstractas

Programacinorientadaa objetosenJava

Laideadeclaseimplementaunainterfaz,esta implementacindebesercompleta,esdecir,detodas lasoperacionesdelainterfaz

PodemostransformarTareaPeriodicaenunainterfaz,deformaqueespecifiquelo quetienequeimplementarcualquierclasequerepresenteunatareaperidica.Este enfoqueproporcionamayorlibertadalahoradedisearlasotrasclases


<<interfaz>> TareaPeriodica

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

TPReloj

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

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

+leerHora():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 B atributoX A C C B atributoX

Herenciamltiple

Programacinorientadaa objetosenJava

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

FiguraGeometrica contiene 1 listaPuntos():Lista almacena *

Poligono

Lista

Segmento

FiguraGeometrica

Poligono

contiene 1

Lista

almacena *

Segmento

aadir(s:Segmento)

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

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

rb:B ra:A

objeto:A

Brb=newA();//Asignacionpolimorfa
Polimorfismo

Programacinorientadaa objetosenJava

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

Elsentidodelpolimorfismoesrealizarunageneraliza cin,olvidarlosdetallesconcretosdeunoovarios objetosdedistintasclasesybuscarunpuntocomna todosellosenunancestro

Polimorfismo

Programacinorientadaa objetosenJava

Lamayoradelasveces,lasconexionespolimorfasse realizandemaneraimplcitaenelpasodeargumentos aunaoperacin.Deestamaneraesposibleescribir operacionespolimorfasquerecibanobjetosde mltiplesclases

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

Programacinorientadaa objetosenJava

Otraaplicacinmuytileslaconstruccinde estructurasdedatosquepuedanmantenerobjetosde distintasclases

VamosaimplementarunanuevaclaseGestorTareasquevaacontenerunalistade tareasarealizar.LallamadaachequearEjecutar()realizarlacomprobaciny ejecucindelastareasquelorequieran


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

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

Programacinorientadaa objetosenJava

Perosiempredebequedarclaroquetraslaconexin polimorfanicamentepodemosaccederalasopera cionespertenecientesalaclaseasociadaalarefe rencia.Elrestodeoperacionesdelobjetonoson accesiblesatravsdeestareferencia

publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TPRelojtpr=newTPReloj(); TareaPeriodicatp; tp=tpr; tp.desactivar();//Ok tp.leerHora()//Error!! tpr.leerHora();//Ok } }


AppGestorTareas.java:XX:cannotresolvesymbol symbol:methodleerHora() location:classTareaPeriodica tp.leerHora(); ^ 1error Polimorfismo

Programacinorientadaa objetosenJava

EnJava,unareferenciaaObjectpuedeserconectada acualquierobjeto,puestoquecomosabemosesun ancestrodetodaslasclases

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

Adems,lasinterfacesimplementadasporunaclase tambinpuedenserutilizadaspararealizarconexiones polimorfas

Polimorfismo

Programacinorientadaa objetosenJava

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

f()

CALL_f
Ligaduradinmica

Programacinorientadaa objetosenJava

ElproblemaapareceenOOPcuandorealizamosuna conexinpolimorfayllamamosaunaoperacin redefinida

A f()

Ar=?? r.f()

f()

f()

CALL_A_f? CALL_B_f? CALL_C_f?

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

Ligaduradinmica

Programacinorientadaa objetosenJava

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

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

Ligaduradinmica

Programacinorientadaa objetosenJava

Portanto,laligaduradinmica,pordefectoenJava, garantizasiemprelallamadaalaversincorrectade cadafuncin,conindependenciadelusodeconexiones polimorfasono

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

Ligaduradinmica

Programacinorientadaa objetosenJava

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

TrascrearunobjetodetipoTPRelojyconectarlomedianteunareferenciaa TareaPeriodica,intentamosrecuperarnuevamenteunareferenciadetipoTPRelojal objeto.Noesposibledemaneradirecta


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

Unsimplecastingpermiteforzarlaconexinala referencia

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

Unintentodecastingimposiblegeneraruna excepcinClassCastExceptionentiempodeejecucin

publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TareaPeriodicatp=newTPReloj();//upcasting TPRelojtr=(TPReloj)tp;//downcastingok //Downcastingimposible:lanzaexcepcinClassCastException TPAvisota=(TPAviso)tp; } }


ExceptioninThreadmainjava.lang.ClassCastException atAppGestorTareas.main(AppGestorTareas.java:XX)

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

Podemoscapturarestaexcepcinparadeterminarsiel objetoapuntadoporlareferenciaesdeltipoesperadoo no,realizandoaccionesdiferentesencadacaso

importjava.lang.*; publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TareaPeriodicatp; TPRelojtr; //Posiblementeenalgnpuntolareferenciatphasidoconectada //conunobjetodelaclaseTPReloj ... try{ tr=(TPReloj)tp; System.out.println(Lahoraactuales:+tr.leerHora()); } catch(ClassCastExceptione){ System.out.println(Lareferenciatpnoapuntaaunobjeto +delaclaseTPReloj); } } }
Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava importjava.lang.*; publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte; //tpesconectadaaalgnobjeto ... try{ tr=(TPReloj)tp; //Operarcontr return; } catch(ClassCastExceptione){ //SinoesdetipoTPReloj,continuamosporaqu } try{ ta=(TPAviso)tp; //Operarconta return; } catch(ClassCastExceptione){ //SinoesdetipoTPAviso,continuamosporaqu } try{ te=(TPEjecucion)tp; //Operarconte return; } catch(ClassCastExceptione){ //SitampocoesdetipoTPEjecucinEntoncesdequetipoes? System.out.println(Error:objetodeclasedesconocida); } } } Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

Muchomscmodoesutilizarinstanceofpara determinasielobjetoesdelaclaseesperadaantesde realizarelcasting

importjava.lang.System; publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TareaPeriodicatp;TPRelojtr;TPAvisota;TPEjecucionte; //tpesconectadaaalgnobjeto ... if(tpinstanceofTPReloj){ tr=(TPReloj)tp; //Operarcontr } else if(tpinstanceofTPAviso){ ta=(TPAviso)tp; //Operarconta } else if(tpinstanceofTPEjecucion){ te=(TPEjecucion)tp; //Operarconte } else System.out.println(Error:objetodeclasedesconocida); } }

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

LaoperacingetClass()deObjectdevuelveunobjeto delaclaseClassquepermiteobtenerentiempode ejecucingrancantidaddeinformacindelaclaseala queperteneceelobjeto.Elatributoestticoclassdela clasetambindevuelveunareferenciaaesteobjeto

importjava.lang.System; publicclassAppGestorTareas{ publicstaticvoidmain(String[]args){ TareaPeriodicatp; //tpesconectadaaalgnobjeto ... Classc=tp.getClass(); System.out.println(Lareferenciatpapuntaaunobjetodelaclase: +c.getName()); Classc=TareaPeriodica.class; if(c.isInterface()) System.out.println(TareaPeriodicaesunaInterfaz); } }

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

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

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

Apartirdelaversin5,Javahaincorporadosimilaral utilizadoporlostemplatesdeC++paraespecificarel tipodeloselementosdelcontenedor Laventajaesquelareferenciadevueltaes directamentedeltipoespecificadoenlacreacindel contenedor

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

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

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

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

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

Informacinde clasesentiempode ejecucin

Programacinorientadaa objetosenJava

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

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

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

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

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

E/Sdecaracteres(readers)

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

VerelapartadoI/O:ReadingandWritingdeltutorial Javaylaspginasdelasclasescitadasenelmanual dereferenciaparamsinformacin

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

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

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

Haydosmtodosdelectura:

Elprimerousalaoperacinparse()delasclaseswrapperdelostiposbsicos Elsegundo,msflexibleysencillo,utilizalaclaseScanner

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

Programacinorientadaa objetosenJava

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

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

VerelapartadoObjectSerializationdeltutorialJava paramsinformacin

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

VamosamodificarahoraelconstructordelaclaseCuentaylaoperacinsalvar() paraqueseancapacesdecargarysalvarelhistoricodemovimientos.Lacapacidad deserializacindeJavapermitesalvarlalistaenlazadadeungolpe


importjava.io.*; importjava.util.*; //EsnecesarioquetantolasclasesClientecomoMovimientoimplementenlainterfaz //Serializableparaquelosobjetospuedanserescritosendisco classMovimientoimplementsSerializable{ Datefecha; chartipo; floatimporte; floatsaldo; publicMovimiento(DateaFecha,charaTipo,floataImporte,floataSaldo){ fecha=aFecha; tipo=aTipo; importe=aImporte; saldo=aSaldo; } } publicclassCuenta{ longnumero; Clientetitular; privatefloatsaldo; floatinteresAnual; LinkedListmovimientos; Otrostemasde intersenJava

Programacinorientadaa objetosenJava

publicCuenta(longaNumero,ClienteaTitular,floataInteresAnual){ numero=aNumero; titular=aTitular; saldo=0; interesAnual=aInteresAnual; movimientos=newLinkedList(); } Cuenta(longaNumero)throwsFileNotFoundException, IOException,ClassNotFoundException{ ObjectInputStreamois=newObjectInputStream(newFileInputStream(aNumero+".cnt")); numero=ois.readLong(); titular=(Cliente)ois.readObject(); saldo=ois.readFloat(); interesAnual=ois.readFloat(); movimientos=(LinkedList)ois.readObject(); ois.close(); } voidsalvar()throwsFileNotFoundException,IOException{ ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream(numero+".cnt")); oos.writeLong(numero); oos.writeObject(titular); oos.writeFloat(saldo); oos.writeFloat(interesAnual); oos.writeObject(movimientos); oos.close(); } //RestodeoperacionesdelaclaseCuentaapartirdeaqu

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

Multitarea.Esposibleimplementarunaovariastareas queseejecutenenvariashebrasdeejecucinen paralelo,delasiguientemanera

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

VerelapartadoThreads:doingtwoormoretasksat oncedelTutorialJavaparamsinformacin

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

Ejemplo:ungestordetareasquefuncionaenparaleloconelrestodelaaplicacin, realizandolacomprobacinperidicadelastareasquerequierenejecucin
importjava.lang.Exception; classDemasiadasTareasextendsException{} publicclassGestorTareasextendsThread{ TareaPeriodica[]tareas; intnTareas,maxTareas; booleanterminar; publicGestorTareas(intaMaxTareas){ super("GestorTareas"); terminar=false; nTareas=0; maxTareas=aMaxTareas; tareas=newTareaPeriodica[maxTareas]; } publicvoidnuevaTarea(TareaPeriodicatp)throwsDemasiadasTareas{ if(nTareas==maxTareas) thrownewDemasiadasTareas(); tareas[nTareas++]=tp; } //Sigue...
Otrostemasde intersenJava

Programacinorientadaa objetosenJava

Laoperacinterminar()vaapermitirforzarlafinalizacindelgestordetareas
//ContinualaclaseGestorTareas publicvoidrun() { System.out.println("Gestordetareasenfuncionamiento"); while(!terminar){ for(intt=0;t<nTareas;t++) if(tareas[t].necesitaEjecucion()) tareas[t].ejecutarTarea(); //Esperarunsegundoantesdevolveracomprobar try{ sleep(1); } catch(InterruptedExceptione){}; } System.out.println("Finalizandogestordetareas"); } voidterminar(){terminar=true;} }

Otrostemasde intersenJava

Programacinorientadaa objetosenJava

Estaaplicacincontaracondoshilosdeejecucinenparalelo,unoprincipalyotro asociadoalgestordetareas
publicclassAppGestorTareas{ publicAppGestorTareas(){} publicstaticvoidmain(String[]args){ GestorTareasgt=newGestorTareas(10); try{ gt.nuevaTarea(newTPReloj()); gt.nuevaTarea(newTPAviso("Hapasado5segundos",5)); }catch(DemasiadasTareasdt){ System.out.println("Mmmm....estonodeberahaberpasado"); } gt.start(); System.out.println("Hilodeejecucinprincipal"); System.out.println("Pulsaunateclaparaterminar"); try{ System.in.read(); } catch(IOExceptione){} System.out.println("Finaldeaplicacin"); gt.terminar(); } } Otrostemasde
intersenJava

También podría gustarte