09 - programacion orientada a objetos herencia

18
354 Programación basada en objetos 8 d) MétodoH obtener para cada pieza individual de datos, los cuales permitan al programador recuperar cualquier pieza de datos en una tigura de manera independiente (por ejemplo, si usted tiene una variable de insnmcia Hu. madu xl, debe tener un método llamado obtenerXl). e) Un método dibujar con la primera línea public va id dibujar ( Graphics g ) que se l!amuní desde el método paint delnpplet pura dibujar una ligura en la puntullu. Si desea pwporcionar más métodos pura uument<lf la ilexibilidad, lo puede hacer. Empiece declurando lu clase MiLinea y un upplct para probar sus clases. El applet deberá tener unu varia- ble de instancia MiLinea llamada linea, que pueda hacer referencia a un objeto MiLinea (creado en el méto- do ini t del applct con coordenadas aleatorias). El método paint del applct deberá dibujar la tigura mediante una insuucción como ésta: linea.dibujar( g); en donde linea debe ser lu rderencia tipo MiLinea y g debe ser el objeto Graphics que será utilizado por la tigum para dibujarse a misma en el applct. A continuación, modilique la referencia Mi Linea ptlfa que sea un arreglo de referencias Mi Linea, y codifi- que varios objetos MiLinea directamente en el programa para dibujarlos. El método paint del applet debení re- correr el arreglo de objetos MiLinea y dibujar cada uno de ellos. Una vez que esté funcionando la parte anterior, deberá declarar las clases Mi Ovalo y MiRect, y deberá agre- gar objetos de estas cl;Isc:; en los ;m·eglos Miovalo y MiRect, El método paint del applet deberá recorrer ca- da uno de estos arreglos y dibujar cada una de las figuras. Cree cinco tiguras de cada tipo. Una vez que el applet esté timcionando, Vol ver a cargar (Re load) en el menú Subprogra- ma (Applet) del contenedor de upplct para volver a cargar el applet. Esto hará que el applet seleccione nuevos números aleatmios para lus figuras. y lns dibujará de nuevn. 1 j !5. En el capítulo lO moditícaremos este ejercicio para aprovechar las similitudes entre las cluses, y así evitur reinvcntnr In meda. Objetivos Programación orientada a objetos: Herencia Comprender cómo la herencia fomenta la reutilización de software. Entender qué son las superclases y las subclases. Comprender el uso del modificador de acceso protected. Utilizar los miembros de supcrclases mediante super. Comprender el uso de los constructores y finalizadorcs en las jcrarquíaB de herencia. Presentar un ejemplo práctico que muestre la mecúnica de la herencia. No digas que conoces a alguien por completo, lw.l'ra que tengas que dividir una herencia con él. Johann Kaspcr Lavater Este método es para definirse como elmímero de la clasl.! de todas las clases similares a la clase dada. Bcrtrand Russell Es bueno heredar una biblioteca, pero es mejor coleccionar una. Augustine Birrcll

Upload: eddie-bo

Post on 12-Jan-2016

29 views

Category:

Documents


0 download

DESCRIPTION

Tema 9 Programación Orientada a Objetos Herencia.

TRANSCRIPT

Page 1: 09 - Programacion Orientada a Objetos HERENCIA

354 Programación basada en objetos Cap~ulo 8

d) MétodoH obtener para cada pieza individual de datos, los cuales permitan al programador recuperar cualquier pieza de datos en una tigura de manera independiente (por ejemplo, si usted tiene una variable de insnmcia Hu. madu xl, debe tener un método llamado obtenerXl).

e) Un método dibujar con la primera línea

public va id dibujar ( Graphics g )

que se l!amuní desde el método paint delnpplet pura dibujar una ligura en la puntullu. Si desea pwporcionar más métodos pura uument<lf la ilexibilidad, lo puede hacer. Empiece declurando lu clase MiLinea y un upplct para probar sus clases. El applet deberá tener unu varia­

ble de instancia MiLinea llamada linea, que pueda hacer referencia a un objeto MiLinea (creado en el méto­do ini t del applct con coordenadas aleatorias). El método paint del applct deberá dibujar la tigura mediante una insuucción como ésta:

linea.dibujar( g);

en donde linea debe ser lu rderencia tipo MiLinea y g debe ser el objeto Graphics que será utilizado por la tigum para dibujarse a sí misma en el applct.

A continuación, modilique la referencia Mi Linea ptlfa que sea un arreglo de referencias Mi Linea, y codifi­que varios objetos MiLinea directamente en el programa para dibujarlos. El método paint del applet debení re­correr el arreglo de objetos MiLinea y dibujar cada uno de ellos.

Una vez que esté funcionando la parte anterior, deberá declarar las clases Mi Ovalo y MiRect, y deberá agre­gar objetos de estas cl;Isc:; en los ;m·eglos Miovalo y MiRect, El método paint del applet deberá recorrer ca­da uno de estos arreglos y dibujar cada una de las figuras. Cree cinco tiguras de cada tipo.

Una vez que el applet esté timcionando, seleccion~ Vol ver a cargar (Re load) en el menú Subprogra­ma (Applet) del contenedor de upplct para volver a cargar el applet. Esto hará que el applet seleccione nuevos números aleatmios para lus figuras. y lns dibujará de nuevn. 1

j

!5. En el capítulo lO moditícaremos este ejercicio para aprovechar las similitudes entre las cluses, y así evitur reinvcntnr In meda.

Objetivos

Programación orientada a objetos:

Herencia

• Comprender cómo la herencia fomenta la reutilización de software.

• Entender qué son las superclases y las subclases.

• Comprender el uso del modificador de acceso protected.

• Utilizar los miembros de supcrclases mediante super.

• Comprender el uso de los constructores y finalizadorcs en las jcrarquíaB de herencia.

• Presentar un ejemplo práctico que muestre la mecúnica de la herencia.

No digas que conoces a alguien por completo, lw.l'ra que tengas que dividir una herencia con él. Johann Kaspcr Lavater

Este método es para definirse como elmímero de la clasl.! de todas las clases similares a la clase dada. Bcrtrand Russell

Es bueno heredar una biblioteca, pero es mejor coleccionar una. Augustine Birrcll

Page 2: 09 - Programacion Orientada a Objetos HERENCIA

356 Programación orientada a objetos: Herencia

'Plan generaC.

9.1 9.i

lntraCiuéció!l····i··.· , < .. · superclasas Y: subclases '

9,3 · Miembrós protédteél, • · . . . 9.4 Relacióf! entre las superddses y los sut:,clases 9,5 Ejemplo prÓCtica: Jerarquicl d~ herencia de Ir.:~~. niv.ol.:~o 9.6 .. Canstructores\r finblizodares en· 9.7 . ; .lng~nierici de s~ftware rnediont~ la. herencia •. Resume11 • :re(111inologi'a Ejt•ri:fc:Íos de autoewlluudó~ • Respuestas~ los i!)erdc'ivsrle atltoeval¡,¡áci<5tl

· 9.1 Introducción En este capítulo, comenzamos nuestra discusión acerca de la programación orientada a objetos (POOl, intro­duciendo una de sus características principales, la herench1, que es una fonna de reutilización de software en la que las clases se crean abwrbiendo los datos (atributos) y métodos (comportamientos) de una clase existente, y se mejoran con nuevas capacidades, o con modificaciones en las capacidades ya existentes. La reutili7.ación de software ahcma tiempo dunmte d desarrollo de programas. También fomenta la reutilización de software probado y depurado de alta calidad, d cual aumenta la probabilidad de que un sistema se implemente con efec­tividad.

Al crear una clase, en vez de declarar miembros (variables y métodos) completamente nuevos, el pro­grnmador puede designar que la nueva clase herede los miembros de una clnse existente. Esta cluse existente se conoce como suprn·lase, y la nueva clase se conoce como subclase. (Otros lenguajes de prognunación, como C++, se reliewn a la superclasc como la c/tl.l'<? bast' y a la subclase corno c/a.w: derivado.) Una vez creada, cada subclase puede convertirse en superclase de futuras subclases. Una Stibclusc generalmente agrega sus propias variabks y métodos. Por lo tanto, una suhdas~ es m<ls especíticu que su superclase y representan un grupo más cspeciulizado de objetos. Generalmcme, ln subclase exhibe los compm1amientos de su supercluse junto con comportamientos adicionales especíticos de esta subclase. La superclase directa es la superclase a partir de la cual la subclase hereda en forma explícita. Una supere/ase indirecta se hereda de dos o m<\s niveles arriba en la jerarquía de clases, la cuul define las relaciones de herencia entre las clases. En Java, la jerarquía de clases empieza con la duse Obj ect (en el paquete java .lang), a partir th: la cual heredan todas las clases en Java, ya sea en forma directa o indirecta. En el caso de la herencia simple, una dase se deriva de una superclase. Ja­va, a diferencia de C++, no sopona la herencia tmíltiplc (que ocun·e cuando una clase se deriva de más de una superclase dirccta).1

La expeiicncia en la creación de sistemas de software nos indica que algunas cantidades considerables de código tratun con casos especiales, estrechamente relacionados. Cuando Jos programadores se preocupan con casos especiales, los detalles pueden oscurecer el panoramn general. Con la programación orientada a objetos, los programadores se enfocan en los elen1entos comunes entre los objetos en el sistema, en vez de enfocm·sc en los casos especiules. A este pro~eso se le conoce como abstrt~cdún.

Es necesario hacer una diferencia entre la relación "es un" y la reluciún "tiene un". Lu relación "es un" representa a la herencia: en este tipo de relación, un objeto de una subclase puede tratarse también como un ob­jeto de sus superclases. Por ejemplo, un auto rs un vehículo. En contraste, la relación "tiene un" identilica a la composición (vea el capítulo 8); en este tipo de relación, un objeto contiene una o más referencias a objetos co­mo miembros. Por ejemplo. un auto tiene un volante de dirección.

Las clases nuevas pueden heredar de las clases en diversas biblimecas de clases. Las organizaciones de· sarrollan sus propi<lS bibliotccus de eluses y pueden aprovechar las q¡1e ya están disponibles en todo el mundo.

l. En d capüulo JO ~xplicarcmos céuno Java puede usur imerfaces para obtener muchos de los beneficios tle la herenciu múlti­ple, evitando al mismo Iiempo Jos prohlemas asociados.

capfiulo 9 Programación orientada a objetos: Herencia 357

Es probable que algún dfa, lu mayoría de software nuevo se construya a partir de componentes relllilizables es­tdndar, como sucede actualmente con la mayoría del hardware. Esto facilitará d desarrollo de software más po­

deroso.

~:9;2 Superclases y subclases ; A menudo, un objeto de una clase "es un" objeto de otra clase también. Por ejemplo, en la geometría un rec­tángulo es un cuadrilátero (al igual que los cuadrados, los parulelognunos y Jos trapezoides). Por lo tan!O, en Javu puede decirse que la clase Rectangulo hereda de la clase Cuadrilatero. En este contexto, la clase cuadrilatero es una superclase. y la clase Rectangulo es una subclase. Un rectángulo es ¡mlipo espe­cílico de cuadrilátero, pero es incorrecto decir que todo cuadrilátero es un rectángulo; el cuadrilátero podría ser un paralelogramo o alguna otra t1gum. En la figura 9.1 se muestran varios ejemplos sencillos de superclascs y subclases.

Como todo objeto de una subclase "es un" objeto de su superclase, y como una superclasc puede tener muchas subclases, el conjunto de objetos representados por una supcrclase generalmente es más grande que el conjunto de objetos representado por cualquiera de sus subclases. Por ejemplo, la supcrclase Vehiculo re­presenra a todos los vehículos, incluyendo autos, camiones, barcos, bicicletas, etcétera. En contraste, In clase Auto representa a un subconjunto más pequciio y específico de todos los vebículos.

Las relaciones de herencia forman estructuras jerárquicas en forma de árbol. Una supcrclusc existe en una relación jcrárquka cnn sus subclases. Aunque las clases pueden exi>tir de manera independiente, cuando par­ticipan en relaciones de herencia se afilian con otws clases. Una clase se conviene ya sea en una supcrclase, proporcionando datos y comportamientos a otras clases, o en una subclase, heredando sus datos y comporta­mientos de otras clases.

Desmrollaremos una jerarquía de clases simple (lo que también se conoce como una jerarr1uía de heren­cia). Una comunidad universitaria tiene miles de miembros, compuestos por empleados. estudiantes y exalum­nos. Los empleados pueden ser miembros del cuerpo docente o administrativo. Los miembros del cuerpo docente pueden ser administradores (como decanos o jefes de departamento) o maestros. Esta estructura orga­nilacionnl produce la jerarquía de herencia descrita en la t1gura 9.2. Observe que esta jerarquía de herencia podría contener muchas otras dases. Por ejemplo, los estudiantes pueden ser graduados o no graduados; lo:; no graduados pueden ser de primero, segundo, tercero o cuarto aiio. Cada flecha en la jerarquía represen tu una rc­lacilÍn "es un". Por ejemplo, al seguir las Jlechas en esta jemrquía de clases podemos decir "un Empleado <'S

1111 MiembroDeLaComunidad" y "un Maestro es Wl miembro Docente". MiembroDeLaComunidad es la supetduse dírecra de Empleado, Estudiante y Exalurnno, y es una supere/ase indirecta de todas las demás clases en el diagrama. Si comienza desde la parte inferior del diagrama, el lector podní seguir las flechas y aplicar la relación es-un hasta la superc!ttse superior. Por ejemplo. un Administrador es w1 miem­bro Docente, es 1111 Empleado y es un MiembroDeLaComunidad.

Otra jerarquía de herencia es la jerarquía Figura de la ti gura 9.3. Pm·a espedlicar que la clase Figura­Bidimensional se deriva de (o hereda de) la clase Figura, la cluse FiguraBidimensional podría declararse en Java de la siguiente manera:

public claas FiguraBidimenaional extends Figura

Superclose

Estudiante

Figura

»res tamo

llmpleado

CuentaBancaria

Subclases

EstudianteGraduado, EstudianteNoGraduado

Circulo, Triangulo, ~ectangulo

PrestamoAutomovil, PreatamoMejoraCasa, Prest~noHipotecario

Docente, Administrativo

cuentaDeChequea, CuentaDeAhorros

Figura 9.1 Ejemplos de herencia.

Page 3: 09 - Programacion Orientada a Objetos HERENCIA

358 Programación orientada a objetos: Herencia CapnuJo 9

Figura 9.2 Jerarquía de herencia para objetos MiembroDeLaComunidad universitario.

Figura 9.3 Jerarquía de herencia para Fig1.1ras.

La herencia no es apropiada para todas las reluciuncs de clases. En el capítulo 8 hablamos sobre la rela­ción riene un, en la que las clases tienen miembros qu~ hacen referencia a los objdos de otras clases.

Tales relaciones crean clases mediante la composición de clases existentes. Por ejemplo, dadas las clases Empleado, FechaDeNacimiento y NumeroTelefonico, no es apropiado decir que un Empleado es una FechaDeNacimiento o que un Empleado es !lll NumeroTelefonico. Sin embargo, un Emplea­do tiene una FechaDeNacimiento y también tieM un NumeroTelefonico.

Es posible tratar a los objetos de supcrclases y a los objetos de subclases de manera similar; sus similitu­des se expresan en los miembros de la superc!ase. Los objetos de todas las clases que extienden a una super­clase común pueden tratarse como objetos de esa superclase (es decir, dichos objetos tienen una relación "es un" con la superclase). Sin embargo, Jos objetos de una superclase no pueden tratarse como objetos de sus sub­clases. Por ejemplo, todos los autos son vehículos pero no lodos los vehículos son autos. En secciones poste­riores consideraremos muchos ejemplos que aprovechan esta rclaci6n.

Un problema con la herencia es que una subclase puede heredar métodos que no necesita, o que no debe tener. A pesar de que un método de superclase sea apropiado para una subclase, a menudo esa subclase requie­re que d método realice su tarea de una manem específica para !u subclase. En dichos casos, la subclase pue­de sobrescribir (redeJ1nir) el método de la superclasc con una implementación apropiada.

En el cupítulo 8 hablamos sobre los modificadores de acceso public y priva te. Los miembros public de una clase son accesibles en cualquier parte en donde el programa tenga una referencia al objeto de esu cla­se, o una de sus subclases. Los miembros pri vate de una clase son accesibles sólo en los métodos de la clase._

capnulo 9 Programación orientada a objetos: Herencia 359

Estos miembros pri vate de la superclase no se heredan. En esta sección presentaremos el modificador de acceso protected. El uso del acceso protected ofrece un nivel intermedio de acceso entre public y priva te. Los miembros protected de una superclase pueden ser utilizados por los miembros de esa su­percluse, por los miembros de cualquier clase que se derive de esa supcrclase y por los miembros de otras cla­ses en el mismo paquete (los miembros protected también tienen acceso a nivel de paquete).

Todos Jos miembros public y protected de unu superclase retienen su modificador de acceso origi­nal cuando se convierten en miembros de la subclase (por ejemplo, los miembros public de la superclase se convierten en miembros public de la subclase y, como veremos pronto, los miembros protected de la su­perclase se convierten en miembros protected de la subclase). Una subclase puede efectu<tr cambios de es­tado en Jos miembros priva te de la superclase, pero sólo a través de los métodos no priva te que se pro­porcionen en la superclase y sean heredados por esa subclase.

Observación de Ingeniería de software 9.1 ·

~Los métodos de una silbe/ase no pueden tener acceso a los miembros priva te de Sil supercla.¡e,

Observación de Ingeniería de software 9.2 íll Declarar datos como pri vate ayuda a los programadores a probar, depurar y modificar cometameme los sis­~ temas. Sí una subclase pude acceder a los datos priva te de su supere/ase, las clases que hereden de esa subcllt­

se podrían acceder a los datos también. Esto propagaría el acceso a /os que debían ser datos privados, y se per­derían los benejidos del ocultamiento de la infomwdrín.

Los métodos de una subclase pueden referirse a los miembros public y protected que se hereden de la superclase con sólo utilizar los nombres de los miembros. Cuando un método de la subclase sobrescribe al método de la superclase, éste último puede utilizarse desde la subclase si se antepone a su nombre la palabra clave super y un punto (. ). En la sección 9.4 hablaremos sobre el acceso a los miembros sobrescritos de la supere Jase.

},9~4 RelaCión emtre las supercloses y los subclases ii En esta sección utilizaremos una jerarquía de herencia Punto/Círculo' para hablar sobre lu relación entre una superclase y unu subcluse. Dividiremos nuestra discusión de la relación Punto/Círculo en varius partes. Prime­ro declararemos la clase Punto, la cual hereda directamente de la clase Obj ect y declara como datos pri­vate a un par de coordem¡dus x-y. Después declararemos !u clase circulo, la cual hereda directamente de la clase Object y declara como datos priva te a un par de coordenadas x-y (que representan la ubicación del centro del círculo) y un radio. No extenderemos la cluse Punto pura crear la clase Circulo; crearemos la clase escribiendo cada una de las líneas de código que se requieran. Después declararemos una clase Circulo2 separada, que extienda a la clase Punto (es decir, un circulo2 es un Punto que también tie­ne un radio) y trate de acceder a los miembros pri vate de la clase Punto; esto producirá errores de compi­lación, ya que la subclase no tiene acceso a los datos priva te de la supcrclase. Luego mostraremos que, si los datos de Punto se declaran como protected, una clase Circulo3 que extienda a la clase J?unto2 podrá acceder u esos datos. Para este fin declararemos la clase Punto2 con datos protected. Ambas clases Circulo contienen la misma funcionalidad, pero mostraremos cómo la clase Circulo3 es más fácil de crear y manejar. Después de hablar sobre la conveniencia de utilizar datos protected, regresaremos los dutos de Punto nuevamente a priva te en la clase Punto3 (para reforzar lu buena ingeniería de software). Luego mostraremos cómo una clase Circulo4 separada, que extiende a !u clase Punto3, puede utilizar los méto­dos de Punto3 para manipular los datos priva te de Punto3.

'!J:Cié(icitihyi;sod~íÍ1ilii:lase Punto , Primero examinaremos la declaración de la clase Punto (ligura 9.4). Recuerde que en Iu secci6n 8.2 vimos _que toda clase en Java (excepto Object) extiende a (o se deriva de) una clase existente. La clase Punto no

2. La relación puma/círculo podría parecer antinatural cuando decimos que un drculo "es un" punto, Este ejemplo enseña Jo que algunas veces s~ conoce como herenda estructural, y se enfoca en la "mect\nica" de lu herencia y en cómo una superclase y un¡t subclase se relacionan enlre sí. En los ejercicios y secciones posteriores, prcsemuremos más ejemplos de herencia natural.

Page 4: 09 - Programacion Orientada a Objetos HERENCIA

360 Programación orientada a objetos: Herencia Capllulo 9

especifica a qué clase ex:tiendc, por lo que implícitamente extiende a la clase Obj ect (paquete java .lang), Los servicios public de la cluse Punto incluyen dos constructores (líneas 9 a 12 y líneas 15 a 20) y los méto. dos eatablecerX (líneas 23 u 26), obtenerX (líneas 29 a 32), eatablecerY (líneus 35 a 38), obte­nerY (líneas 41 a 44) y toString (líneas 47 a 50). La dasc Punto especifica a lus variables de instancia Jt

y y como priva te (líneas 5 y 6), por lo que los objetos de otras clases no pueden acceder a x y Y de manera directa. Técnicamente, aun si lus variables de instancia x y y de Punto fueran públicas, Punto nunca podría mantener un estado inválido; las variables de instancia x y y de un objeto Punto no pueden contener valores inválidos, ya que el plano de coordenadas X· Y es infinito en ambas direcciones. No obstante y en general, al de. clarur Ius variables de instancia como pri vate y al proporcionar métodos obtener y establecer pura manipu­lar y validar las variables de instancia, se refuerza la buena ingeniería de software.

Observación de ingeniería de software 9.3 00 El eumpilador de Java eswblece la supere/ase de 11110 dase e11 Object cua11do el programa 110 especijicu una Su· e pe re/ase en fomw explíciw.

1 2 3

1/ Fig. 9.4: Punto.java 11 La declaración de la cl,1se Punto representa un par de coord~nildas x-y.

4 publTc 91/iss fPI;in~o { 5 ... privateAnt>x{'Í/ parte )fd~ •ur(par i:lé ci:io:rd'enaCiaS: 6 P#~~~E! :tnt:. jY/,[/!' paft.i '!: §{~¡¡ .f?fll\ de c¡om:g·~l\á.d~~ 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

/1 establecer x en el par de coordenadas public vold establecerX ( int valorX 1 (

x , valorX; 11 no hay necesidad de validación

11 devuelve :< del par de coocdenadas public int obtenerX() (

return x;

11 es tablece1· y en el par de coordenadas public vo.ld establecerY( int valorY l {

y ::¡ valorY: 11 no hay necesidad de validación

Figura 9.4 la clase Punto represento un par de coordenadas x·y, (Parte 1 de 2.)

capffulo 9 Programación orientada a objetos: Herencia 361

40 // devuelve y del par de coordenadas 41 public int obtener Y ( 1 42 { 43 retum y;

44 45 46 47 48 49 50 51 52 ) 11 fin de la clase Punto

figura 9.4 La clase Punto representa un par de coordenadas x-y. (Parte 2 de 2.)

Los const.tuctores no se heredan; por lo tanto, la clase Punto no hereda el constructor de la clase Obj ect. Sin embargo, los constructores de Punto llaman al constructor de la clase Obj ect en fonna implícita. De he· cho, la primera tarea del constructor de cuulquier subclase es llamar al constructor de su superclusc directa, ya sea en forma implícita o explícita. (Más adelante en esta sección, describiremos la sintaxis para llamar explíci· tamente al constructor de una superclase.) Si el ccídigo no incluye una Humada explícita al constructor de la supcrclase, Java llama implícitamente al constructor predeterminado o sin argumentos de la supcrclase. Los comentarios en las líneas 11 y 17 indican en dónde ocurren las llamadas implícitas al consn11ctor predetermi­nado de la clase Obj ect.

El método tostring () (líneas 47 a 50) es especial. Toda clase en Java (como la clase Punto) hereda, ya sea en forma directa o indirecta, de la clase Obj ect,la cual es la raíz de la jerarquía de clases en Java. Como io dijimos ¡¡ntcliormente, esto signiJica que. cada clase hereda los métodos de lu clase Obj ect. Uno de esos métot!os es tostring, que devuelve una representación String de un objeto. En oq1siones el progr.mm llama u este método en forma implícita, como cuando un objeto se concatena a una cadena. El m~tmlo toString original de lu clase Obj eat es una versión genérica, que se utiliza principalmente para guardnr un espacio y puede ser sohrescrito por una subclase (como lo hacemos en los applcts con los métodos ini t, start, y paint de !u dase JApplet). El método toString de la clase Punto sobrescribe al método toString de lu clase Obj ect; al ser invocado, el método toString de la clase Punto devuelve un obje!O String que contiene un par ordenado de los valores x y y (línea 49). Pura sobrescribir un método de una superclase, una subclase debe declarar un método con la misma tirma (nombre y parámetros) que el método en la superclase.

~' Error común de programación 9.1 ~ E.> 1m error de sillltLtis sobrescribir u11 método con 1m modificador de acceso mds restringido. Un método publi a !j]:J de la supere/ase no puede convertirse en un método proteated o prívate en/a s1¡bc/ase.

En la figum 9.5 se prueba la clase Punto, En la línea 9 se crea UI!U instancia de un objeto Punto llama· do punto y se pasan al constructor el número 72 como valor para la coordenada x, y el número 115 como va· lor para la coordenada y. En las 'líneas 12 y 13 se utilizan los métodos obtenerx y obtenerY de punto pura recuperar estos valores, y se anexan a la cadena salida. En las líneas 15 y 16 se invoca u los métodos eatablecerX y eatablecerY de punto pura cambiar los valores de las variables de instancia x y y de punto. En la línea 19 se concatena punto a una cudena,la cual llama implícitamente al método toString de punto pura obtener la representación de cadena del objeto. Al concutenar una cadena con cualquier objeto se produce una llamada implícitu al método toString tlcl objeto, pura obtener una representación de cadena del mismo; luego se concatenan las cadenas. En la línea 21 se muestra la cadena salida al llamar al método showMessageDialog de JOptionPane.

lf..Cíiéiciówde rm.a éliise i51raiilo sin milimr Jzereli~ía\ Ahora veren\os la ~cgunda parte ele nuestra introducción ;¡la herencia, en donde declararemos y probaremos la (completamente nueva) clase Circulo (tiguru 9,6), que contiene un par de coordenadas x-y (las cuales indi·

Page 5: 09 - Programacion Orientada a Objetos HERENCIA

362 Programación orientada a objetos: Herencia Capftulo 9

can el centro del círculo) y un radio. Los servicios públicos de la clase Circulo incluyen los dos constructo­res de Circulo (llncas JO a 13 y líneas 16 a 22) y los métodos establecer! (Hneas 25 a 28), obtenerx (líneas 31 a 34), establecerY (líneas 37 a 40), obtenerY (líneas 43 a 46), establecerRadio (líneas 49 a 52), obtenerRadio (líneas 55 a 58), obtenerDiametro (líneas 61 a 64), obtenerCircunfe~ rencia (líneas 67 a 70), obtenerArea (líneas 73 a 76) y toSt;ring (líneas 79 a 82). En las líneas 5 a 7 se declaran las v:uiables ¡e, y y radio como variables de instancia pri vate. Estas variables y métodos en­capsulan todas las características necesarias (es decir, la ''geometría analítica") de un círculo. En la sección 9.5 mostraremos cómo este encapsulamiento nos permite reutilizar y extender esta clase.

1 2 3 4

/1 Fig. 9.5: PruebaPunto,java /1 Prueba de la clase Punto. import javax.swing.JOptionPane;

5 public class PruebaPunto ( 6 7 6 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

public static void ma.Ln( String[] args ) (

11 obtener las coordenadas del punto su:ing salida = "La coordenada x es " + pul1t:oicotlcié"rkU +

"\nLa coordenada Y es • + ijí.mto',(¡bt¡;ner):'J); --- - --

ourito_:és_Bt;w_··_1ece_'rx_ rúO: 'l~i' /t esblbiecer;:ta' 'é;óordeilád.a:"~i ~unto.eatoJ;>i~~~hL2b );; ;11 ;esc~b1~ckJca ca4id<;!n~ª~-~~!

JOptiot1P¿¡ne. showMessageDialog 1 null, salida 1 ; 11 mostrar resultados

Sys tem. exi t ( O 1 ;

11 fin de main

11 fin de la clase PruebaPunto

Figura 9.5 Programa de prueba para la clase Punto,

1 2 3

1/ Fig. 9.6: Circulo.java /( La cl.ase Circulo contiene un par de coordenadas x-y y un radio,

4 public class Circulo {

: ~~t~~r:ri~g~_;;'·~·:--}¡:;:d~;r::;~~¡1 g~g~:~:::)~:E:·&:~~~r.~:f~:¿t~~~r~ 7 priva te double radio; ¡ 1 radio del cüculo

Figura 9.6 La clase Circulo contiene una coordenada x-y y un radio. (Parte 1 de 3.)

capftulo9 Programación orientada a objetos: Herencia 363

8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

/1 constructor sin argumentos public Circulo () {

11 la llamada impllcita al constructor de Qbject ocurre aquí

1/ constructor public Circulo ( lnt valor X, int valorY, double valorRadlo 1 {

11 la llamada implícita al constructor de Object ocurre aqul

~~~if~~fJJ.JJ,lJr~21~]a1:~!:~~:~~l-~~i'i;~~~~?I~~'

11 establecer el radio public void establecerRadio( double valorRadio 1

{

radio~ { valorRadio < 0.0 ? 0.0 : valorRadio );

/1 devuelve el radio public double obtenerRadio() {

return radio;

11 calcula y devuelve el diámetro public double obtenerDia.met:r0 ( 1

Figura 9.6 La clase Circulo contiene una coordenada x-y y un radio, (Parte 2 de 3.)

Page 6: 09 - Programacion Orientada a Objetos HERENCIA

364 Programación orientado o objetos: Herencia

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

return 2 * radio¡

11 calcula y devuelve la chcuníerencia public double obtenerCircunferencia(l (

return Math.PI * obtenerDiametro();

11 calcula y devuelve el área public double obtcnerArea(l {

retum ~lath.PI * radio • radio;

11 devuelve representación String del objeto Circulo public String toString() (

return '1Centro = 1/]!; Radio

11 fin de la clase Clrculo

'' + radio;

Figura 9.6 La clase Circulo contiene una coordenada x-y y un radio. (Parte 3 de 3.)

1 2

11 F'ig. 9. 7: PruebaCirculo. java 11 Prueba de la clase Cü-culc·.

3 lmporl; java. text. DecimalFormat; 4 lrnport jav.u. swing. JOptionPane; 5 6 7 8 9

public class PruebaCirculo {

public static void main( String[l args 1 {

11 obtener las coordenadas x-y y radio iniciales de Circulo String salida = "La coordenada >: es " + dr;c\¡'lp,i()Rt~né.~~;:,('); +

"\nLa coordenada Y es " + ci:i;culo.:obEener'{l:) + "\nEl radio es " + ~i~.C::¡¡ICÍ~o]j_teiierRªgi:¡¿JJ;

Capftulo 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

11 da formato a los valores de punto flotante con 2 dígitos de precisión oecimalFonuat dosPigitos = new PecimalFormat( "0.00" i;

/1 obtener el diámetro del Circulo

Figura 9.7 Programa de prueba para la clase Circulo, (Parte 1 de 2.)

capftuio9 Programación orientada a objetos: Herencia 365

salida += "\nEl diámetro es " +

dosPigi tos. forma t { g~Jf.cjY~cj i,2li~,¡¡_¡¡~~!:í~@l_egt§]¡j¡ l ;

1/ obtener la circunferencia del Clrculo salida += 11 \nLa circunferencia es 11 +

dosDigitos. format ( (i'i¡f¡ú)i¡j,ol:ft;eji~:¡;~t~~U,n(@:~M~~lJj ) :

11 obtene.r el área del Circulo salida += "\n8l área es " + dosDigitos. format ( i:¡!jfq~Jr~ifcj~te:ti@;i'r~'i¡J.)l ) ;

JOptionPane. showMessageDialog { null, salida ) ; 11 muestr¿¡ l¿¡ salida

System. exit i O 1;

11 fin de rnain

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 11 fin de la clase PruebaCirculo

Figuro 9.7 Programa de prueba para la clase Circulo. (Parte 2 de 2.)

En la tigura 9.7 se prueba la clase Circulo. En la línea LO se crea una instancia de un Circulo. se pasa al constructor el número 37 como el valor de la coordenada x, el número 43 como el valor de la coordenada y, y 2. 5 como el valor del radio; después se asigna la referencia del objeto a circulo. En las líneas 13 a 15 se utilizan los métodos obtenerX, obtenerY y obtenerRadio pura recuperar los valores de circulo, y se anexan estos valores a la cadena salida. En las líneas 17 a 19 se invoca u los métodos establecerX, establecerY y establecerRadio i.le circulo para cambiar las coordenadas x-y y él radio, respecti­vamente. El método establecerRadio (tigura 9.6, líneas 49 a 52) se asegura de que a la variable de instancia radio no se le pueda asignar un valor negativo (es decir, un círculo no puede tener un mdio negativo). En las líneas 22 y 23 de la tigura 9.7 se hace una llamada al método tostring de circulo en forma explícita, pa· ru obtener la representación de cadena del nuevo objeto circulo. En las líneas 29 a 37 se hacen llamadas a los métodos obtenerPiametro, obteuerCircunferencia y obtenerArea de circulo para ob­tener el diámetro, la circunferencia y el área de circulo, respectivamente. En la línea 39 se muestra la cade­na de salida.

Observe que gran parte del código para la clase Circulo (ligura 9.6) es similar, si no es que idéntico, al código pura la clase Punto (tigura 9.4). Por ejemplo, en la dase Circulo las vari;1bles de instancia prí­vate ::e e y y los métodos establecerX, obtenerX, establecerY y obtenerY son idénticos a los de la clase Punto. Además, los constructores de Circulo son cnsi idénticos a los de la clase Punto, con la ex­cepción de que también manipulan el radio. Las demás adiciones a la dasc Circulo son lu variable de ins· tancin prívate llamada radio y los métodos establecerRadio, obtener:Radio, eetablecer­Diametro, establecercircun:ferencia y obtenerArea.

Parece que copiamos el código de la clase J?unto, que lo pegamos en la clase Circulo y que después modificamos la clase Circulo para incluir el radio y los métodos que lo manipulan. Este método de "copbr

Page 7: 09 - Programacion Orientada a Objetos HERENCIA

366 Programación orientada a objetos: Herencia Capilulo 9

y pegar" es a menudo propenso a errores y muy tardado. Peor aún, puede provocar muchas copias físicas del mismo código existente a través de un sistema, creando una pesadilla para mantener el código. ¿Existe alguna manera de "absorber" los alributos y comportamientos de una clase, de manera que los haga parte de otras cla· ses sin tener q\IC duplic;u· código'? En los siguientes ejemplos contestaremos esa pregunta, utilizando un méto. do de constmcción de clases más elcg;mtc que enfatiza los beneficios de la herencia.

, ,Jer¡¡rquía Punta/Circulo 11tilizmzdo l¡ere11cia "'Ahora declararemos y probaremos la clase Circulo2 (figura 9.8), la cual hereda las variables de inst:mcia :x:

y y, junto con los métodos establecerX, obtenerX, establecerY y obtenerY de la clase !?unto (figura 9.4). Un objeto de la clase Circulo2 "es un" Punto (ya que la herencia le pasa las capacidades de la clase Punto) pero, según la evidencia que proporciona lu clase Circulo2, también contiene la variable de instancia radio (ti gura 9.8, línea 5). La palabra clave extends en la línea 4 de lu declaración de clase indi· ca la herencia. Como una subclase, Circulo2 hercdu las variables de instancia y los métodos public y protected de la clase Punto. Los consu·uctores de la clase Punto no se heredan. Por lo tnnto, los servi­cios públicos de Circulo2 incluyen a los dos constructores de Circulo2 (líneas 8 a 20) (cada clase pro­porciona sus propios constructores que son específicos para la clase); los métodos public heredados de la clase !?unto; los métodos establecerRadio y obtenerRadio (líneas 23 a 32); y los métodos obte· nerDiametro, obtenerCircunferencia, obtenerArea y toString (líneas 35 a 57).

1 2 3

/1 Pig. 9.8: Circulo2.java /1 La clase Cüculo2 hereda de Plmto.

4 vuPH:" c~ass;:éir:al.(ió4~r~~1:€l!1,dJ.!'J?~(l~9 ¡ 5 pdvQ.te double radio; 11 El radio de Circulo2 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

11 constructor sin argumentos pub¡ic Circulo2() {

11 la llamada implícita al constructor de Punto ocurre aqui

11 constructor public Circulo2 ( int valorX, int valorY, double valorRadio ) (

11 la llamada imolicita al constructor de Punto ocurre

~i,;_:~~:~{i-:'¡\j,i1'~~"\~-~f~t~~;;~ct~)~~~~~~-~~.1:~1

ck~~~g establecerRadio( valorRadio !;

11 establecer el radio public void establecerRadio( double valorRadio ) {

r?dio ~ ( valorRadio < 0.0? 0.0 : valorRadio );

11 return radio public double obtenerRadio() {

return ¡:adio;

/1 calcular y devolver el diámetro

aqui

Figuro 9.8 Los miembros priva te de la superclase no son accesibles en lo subclase. (Parte 1 de 2.)

copftulo 9 Programación orientada a objetos: Herencia 367

35 public doubl e obtenerDiametro () 36 ( 37 return 2 • radio; 38 39 40 // calcular y devolver la circunferencia 41 public double obtenerCircunferencia() 42 { 43 return Matl1. PI * obtenerDiametro (); 44 45 46 11 calcular y devuol ver el área 47 public double obtenerArea() 48 { 49 r-e turn M a th. PI • radio * radio;

50 51 52 11 devolver la representación String de un objeto Circulo 53 pl)blir,: String toString () 54 { 55 56 57 58 59 11 fin de la clase Circulo2

Figura 9.8 Los miembros priva te de lo superclose no son accesibles en lo subclase. (Parte 2 de 2.)

El constructor sin argumentos (líneas 8 a 11) llama implícitamente al constructor sin argumentos de la cla· se Punto; después Java establece implícitamente las coordenadas X·Y en O. El otro constructor (líneas 14 a 20) llama implícitamente al construcwr sin argumentos de la clase !?unto y después establece la coordenada x-y en un valor específico. El compilador genera errores de sintaxis para las líneas 17 y 18 (y la línea 56, en don­de el método toString de Circulo2 trata de utilizar los valores de :x: y y directamente), ya que la subcla­se Circulo2 no hu heredado, y por lo tanto, no se le permite acceder a las variables de instanciaprivate x e '1 de la superclase Punto.

''11irtzr1Jii(aiiurii::a!Ciraulo utiliza11do dato.v ,Prot:ected' Para permitir a la clase Ci~cui'o2 a~ceder a las variables de instancia x y y de la supcrclase, podemos de­clarur esos miembros como protected, en la superclase. Como dijimos en la sección 9.3, los miembros

Page 8: 09 - Programacion Orientada a Objetos HERENCIA

368 Programación orientada o objetos: Herencia Copllulo 9

protected de una superclase son heredudos por cualquier subclase de esa superclase. La clase Punto2 (fi­gura 9.9) es una modiiicación de la clase Punto (figura 9.4), la cual declara las variables de instancia x y y

como protected (figura 9.9, líneas 5 y 6) en lugar de pri vate. Además de haber cambiado el nombre de lu clase (y por consecuencia, haber cumbiado el nombre del constructor) u Punto2, el resto de la declamción de clase de la figura 9.9 es idéntico a la tigura 9.4.

¡¡ Fig. 9.9: Punto2.java 2 // La declaración de la clase Punto2 representa un par de coordenadas x-y. 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

// constructor sin argumentos public Punto2 1) {

11 la llamada implícita al constructor de Object ocurre aquí

11 constructor publ.lc Punto2 1 int valorX, int valorY 1 {

11 la llamada implícita al constructor de Object ocurre aquí x valorX; i i no ·hay necesidad de validación y • valorY; 1/ no hay necesidad de validación

11 establecer x en el par de coordenadas publ.Lc void establ.oceJ:XI int valorX ) {

x • valorX; // no hay necesidad de validación

i/ devolver x del par de coordenadas public int obtenc;rX 1) 1

return x;

11 establecer y en el par de coordenadas publlc void establecerY( int valorY ) {

y • valorY; 11 no hay necesidad de validación

/1 devolver y del par de coordenadas public int obtener Y ( 1 {

return y;

/1 devolver la representación String del objeto Punto2 public Stri.ng coStdng 1) {

Figura 9.9 La clase Punto2 representa un par de coordenadas x-y como datos protected. (Porte 1 de 2.)

capnulo 9 Programación orientada a objetos: Herencia 369

49 50 51 52

return 11 [ 11 + x .,. 11 u + Y + , j 11 i

11 fin de la clase Punto2

Figura 9.9 Lo clase Punto2 representa un par de coordenadas x-y como dolos protected. (Parte 2 de 2.)

La clase Circulo3 (figura 9.10) es una moditicación de la clase Circulo2 (figura 9.8) que extiende a la clase Punto2 en vez de Punto. Como la dase Circulo3 extiende a la clase Punto2 (línea 5), los objetos de la clase Circulo3 heredan las variables de instancia que se declararon como protected en la clase Punto2 (es decir, las variables x y y). Como resultado, el compilador no genera mores al compilar el constructor de Circulo3 en las líneas 15 a 21, y el método toString en las líneas 54 u 57, ya que x y y ahora son miembros de la dase Circulo3. Los objetos de una subclase también heredan los miembros pro­tected de cualquiera de las supcrcluses indirectas de esa subclase.

1 2 3 4

/! Fig. 9.10: CirculoJ.java 11 La dase Circulo3 hereda de Punto2 y tiene acceso 11 protected x y y de Punto2.

a los miembros

5 plibrlc ('lass C~iculo3 e~ten~s Punlo2 { 6 pri vate double radio; 11 el radiü de Circulo3

7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

11 constructor sin argumentos public Circulo31) i

11 la llamada impliclta al con~t1:uct:or dE: Punto2 ocurre; aquí

1 1 Ct¡ns truc to r publ.i e Circulo3 { int valorX, i.nt valorY, double valorRadio 1 {

11 la llamada implícita al constructor de Punto2

;:)~rm~~~;~t¡'1~~-f~~¡~~i·,~~mt~:.~,~ti:u~:~r~~ establece¡·Radio 1 valorRadio 1;

11 establecer el radio public void establecerRadiol double valorRadio 1 {

radio ~ 1 valorRadio < 0.0 ? 0.0 : valorRadio i;

11 return radio public double obtenerRad.lo 1) {

recurn radio;

1/ calcular y devolver el diámetro public double obtenerDiillnetro() {

ocurre aquí

Figura 9.10 Close C:irculo3 que hereda los datas protected de Punto2. (Parte l de 2.)

Page 9: 09 - Programacion Orientada a Objetos HERENCIA

370 Programación orientada a objetos: Herencia Capftuio9

38 return 2 * radio; 39 40 41 11 calcular y devol ve¡:- la circunferencia 42 publ.Lc double obtenerCircunferencia 1) 43 44 return Math,PI • obtenerDi.ametrol); 45 46 47 11 calcular y devolver el área 48 public double obtenerAreal) 49 { 50 return Math. PI • radio * radio¡ 51 52 53 11 devolver la representación String de un objeto Ci.rculo3 54 public String toString 1) 55 { 56 retúrn ~c;éntr:o: ;,'['' 57 58 59 /1 fin de la clase Circulo3

Figura 9.10 Clase Circulo3 que hereda los datosprotected de Punto2. (Parte 2 de 2.)

La cluse Circulo3 no hereda los constructores de la clase Punto2. Sin embargo, el constructor sin ar­gumentos de la clase Circulo3 (líneas 9 a 12) llama al constructor sin argumentos de la clase Punto2 en forma implícita. Recuerde que la primera tareu del constructor de cualquier subclase es llamar al constructor de su superclase directa, ya sea en forma implídtu o explícita. Si el código no incl\tye una llamada explícita al constructor de la superclase, se hace una llamada implícita al constructor sin argumentos de lu supercluse. El constructor de las líneas 9 a l2llama primero al constructor sin argumentos de Punto2, y después Java ini­cializa las variables heredadas y establece radio en sus valores predeterminados de cero.

En la figura 9.11 se realizan en la clase Circulo3 pruebas idénticas a las que se realizaron en la figura 9.7 para la clase Circulo (Jigura 9.6), Observe que los resultados de los dos programas son idénticos. Aun­que declaramos a la clase Circulo sin utilizar la herencia y declaramos u la clase Circulo3 utilizando la herencia, ambas clases proporcionan la misma funcionalidad. El código fuente para la clase Circulo3, que consta de 59 líneas, es considerablemente más corto que el código fuente de la clase Circulo. que es de 84 líneas, ya que la clase Circulo3 hereda parte de su funcionalidad de Punto2, mientras que la clase Circulo no hereda ninguna funcionalidad. Además, ahora hay solamente una copia de la funcionalidad del punto que se mencionó en lu clase Punto2. Esto hace que el código sea más fácil de depurar, mantener y mo­dificar, ya que el código relacionado con el punto existe sólo en el archivo de la figura 9.9.

1 2

1/ Flg. 9.11: PruebaCirculo3.java 1/ Prueba de la clase Clrculo3.

3 import java, text.DecimalFormat; 4 import j ·>Va:<. swing. JOpdonPanr=; 5 6 7 8 9

public class PruebaCjrculo3

public static void mainl String[] args ) {

Figura 9.11 Los miembros protected de la superclase se heredan en la subclase Circulo3. (Parte l de 2.)

capftulo 9 Programación orientada o objetos: Herencia 371

1/ crear instancia de objeto Circulo

1/ obtener coordenadas x-y y radio iniciales de Circulo3 String sali.d>l = "La coordenada X es " + ~~tt:l.l:\)?;l<?,l;Jt_&fiéi'X'I') t

"\nLa coordenada Y es " + ,g-r~91,!Ío!9!Jl;I;!Í1e¡!'(:ÍJ: ~ --- " "\nlU radio es " , q~j:'cii,tí'QI;?qji~ehsíi)'.ig:\.~ ();

11 obtene.r representación String del nuevo valor de circulo salida r= "\n\nLa nuevu ubicación y radio de circulo son\n"

Éircl,!J\li.~ª§~~~ng:l)j

11 dar formato a los valm·es de punto flotante <;:on 2 digitos de precisión DecimalFormat doaDigitos = new DecimalFormatl "0.00" );

1/ obtener el diámetro del Circulo salida += j, \nEl diámet.ro es " +

dosDigi tos. forma t 1 c:;i~culoi obténe¡,']}iajrícit_ro 1'); ) ;

11 obtener la circunferencia del Circulo salida += "\nLa circunferencia es " +

dosDigitos. fo¡111at 1 ,;:_:j.ic\j:J;9:obte~rol:clr'cunl:!=J;eridaO ) ;

11 obtener el área del Circulo salida. r= "\nEl áre,1 es " + dosDigitos. format 1 ~iíé~u~ó';bp:_te~~E'i~f;.aO: ) ;

JOptionPane.show~!essageDialogl nuli, salld¿¡ ) ; 1/ mostrar salida

Syste¡n.exltl O);

11 fin del método main

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 1/ fin de la clase PruebaCirculo3

Figura 9.11 Los miembros protected de la superclase se heredan en la subclase Circulo3. (Parte 2 de 2.)

En este ejemplo declartmws lus variables de instancia de lu superclase como protected, paru qu~ las subclases pudieran heredarlus. La herencia de las variables de insnmcia protegidas permit~ un ligero aumento en el rendimiento, ya que evitamos incurrir en la sobrecarga de una llamudu a un método establecer u obtener.

Page 10: 09 - Programacion Orientada a Objetos HERENCIA

372 Programación orientada o objetos: Herencia Capfrulo 9 .

Sin embargo, dichos aumentos en d rendimiento son a menudo insignificantes, en comparación con las opti­mizaciones que los compiladores pueden realizar. Es mejor utilizar datos pri vate pura fomentar la buena in­geniería de software. Su código será más fácil de muntener, modiJicar y depurar.

El uso de variables de instancia protected crea dos problemas. En primer lugar, el objeto de la subcla­se no tiene que usar un método para establecer el valor de la variable. Por lo tanto, el objeto de una subclase puede asignar un valor inválido a la variable, dejando así ai objeto en un estado inconsistente. Por ~jemplo, si declaráramos la variable de instancia radio de Circulo3 como protected, el objeto de una subclase (por ejemplo, Cilindro) podría entonces asignar un valor negativo a radio. El segundo problema debido al uso de variables de instancia protected es que hay una mayor probabilidad de que los métodos de la subclase se es~riban de tmmera que dependan en la implementación de la subclase. En la práctica, las subclases deben depender solamente de Jos servicios de la supcrclusc (es decir, de los métodos que no sean priva te), y no de su implementación. Con vmiables de instancia protected en la supercluse, si cambia la implementación de la superclase, tal vez tengamos que modificar a todas las subclases de esa superclasc. Por ejemplo, si por alguna razón cambiáramos los nombres de las variables de instancia x y y a coordenadaX y coordenada Y, en­tonces tendríamos que hucerlo en todas las ocurrencias en las que una subclase hiciera referencia a estas variables de inst;mcia de la superclase directamente. En tul caso, se dice que el software es ji·ágil o quebradizo, ya que un pequeño cambio \~n la superclase puede "quebrantar" la implementación de la subclase. El programador de­be ser capaz de modificar la implementación de la clase libremente, sin tener que dejar de proporcionar los mis­mos servicitJs a las subclases. (Claro que, si cmnbiun los servicios de la superclase debemos rcimplemenlar nuestras subcluses, pero el buen diseño orientado u objetos trata de evitar esto.)

.. ,. Buena práctica de programación 9.1 ~ Use elmodijicador de acceso protected cumulo una supetdase deba propon:ionar 1111 servicio (es decil; wrmé­lkLJ todo) slilo a sus sube/oses y 110 a otros clientes.

o-:--' Buena práctica de programación 9.2 p¡:;-~ Declare aJa:¡ variables de illstc/llcia de la Sti]Jeldcrse como p.rivate (en vez de protected) para que la imple­rn me/1/rtddn de la .l'llperclctse Jllleda cmnhiar sin aj<•cmr ll las implementaciones de las snbc/ose.\·.

. Tip para prevenir errores 9.1

® Siempre que sea posible, evite incluir l'ctriables e/,, ins1ancin protected en una supere/ase. Eu vez de ello, inclu-yo me todos 110 priva te que ulilicenalas variables de inswncic¡ pri.vate, para usegumr que el obje10 manten­gawr es/(/do consisiL'I!te.

Jerarquía Punto/Circulo utilizando datos prívate Ahora reexaminaremos una vez más nuestro ejemplo de la jerarquía Punto/Circulo. tratando esta vez de utilizar las mejores prácticas de ingeniería de software. En la clase Punto3 (figura 9.12) se declaran las varia­bles de instancia x y y como priva te (líneas 5 y 6), y se exponen los métodos establecerX, obtenerX, establecerY, obtenerY y toString para manipular estos valores. La subclase Circulo4 (figura 9.13) hereda estos métodos no pri vate de la superclase (establecerX, obtenerX, establecerY y ob­tenerY) y puede acceder a los miembros priva te de la superclasc mediante estos métodos.

1 // Pic¡. 9.12: Punto3.java 2 11 La decla1·aclón de la clase Punto representa un par de coordenadas x-y. 3 4 public class Punto3 ( 5 pd.Yá'te .i(l(:¡q // paÜe K de ',\B~p).r ae ;CÓoi:der\ad~s 6 E.>Í:'i:V¡¡.te :Lnt',y; e il patl;:e y de .Jtn Jia:!C'tle: c9otd!'ria~~ 7 8 11 constructor sin argumento¡¡ 9 public Punto3()

Figura 9.12 La clase Punto3 utilizo métodos poro manipular sus datos pri vate. (Porte 1 de 2.)

cap~ulo 9 Programación orientada a objetos: Herencia 373

11 la llamada implícita al constructor de Objact ocurre aqui

/1 constructor public Punto]( int valorX, int valorY 1 (

11 la llamad¡¡ implícita al conr.tructor de Object ocurre aqui x valorX; 11 no hay necesidad de validación y valorY; //no hay necesidad de validación

11 establecer x en el par de coordenadas public void establecerXI int valorX ) (

x- valorX; // no hay necesidad de validación

/1 devolver x del par de coordenadas public int obtener X ( 1 (

ret:urn ;"<:

(/ establecer y en el par de coordenadas public void establecerY( int valorY ) {

y - valorY; 11 no hay necP-sidad de validación

11 devolv8.r y dP.l par de coordenadas public int obtener Y {)

{ return y;

11 devolver la representación String del objeto Punto3 public string toString() ( .

10 11 12 13 14 15 1ó 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 /1 fin de la clase Punto3

Figura 9.12 Lo clase Punto3 utilizo métodos paro manipular sus datos pri vate. (Porte 2 de 2.)

La clase Circulo4 (figura 9.13) tiene varias modificaciones en las implementaciones de sus métodos, que la diferencian de la clase Circulo3 (figura 9.10). El constructor de la clase Circulo4 (líneas 16 a 20) invoca a un consuuctor de Punto3 para inicializar la porción correspondiente a la superclase de un objeto Circulo4 (es decir, las v:uiables x y y heredadas de Punto3). En realidad, Java requiere que el constructor de una subclase llame al constructor de su supcrclase para inicializar las variables de lnstuncia de la superclu­se que son heredadas por !u subclase. El constructor sin argumentos de las líneas 1 O a 13 no Huma a un cons­tructor de Punto3 en forma cxplídtu, por lo que Java llama automáticamente al constructor sin argumentos de ln clase Punto3 (declarado enlns líneas 9 u 12 de la figura 9.12).

Page 11: 09 - Programacion Orientada a Objetos HERENCIA

374 Programación orientada a objetos: Herencia Capuulo 9

1 // Fig. 9.13: Circulo4.java 2 11 La clase Circulo4 hereda de Punto3 y accede a las variables x Y Y 3 11 de Punto 3 mediante los métodos public de Punto3, 4 s ~~~fcr: éJ:~s~Eg~~~~!J:§4' ett:e,i{éfs:: P't\'!tó,~ 1 6 7 prlvate double radio¡ í 1 El radio de Clrculo11

a 9 11 constructor sin argumentos

10 public Circulo'! 1} 11 { 12 13 14 15 11 constructor 16 public Circulo4 1 int valorX, int valorY, double valorRadio ) 17 { 18 super 1 v<itéiri; valor'( ) i íi üama{e:.:P,lí~_i.t~en,t§';a1,cónstl:':l:CtorAe Púntó:l 19 establecerRadio( valorRadio }; 20 21 22 1! establecer el radi.o 23 public void establecerRadio 1 double valorRadio ) 24 { 25 radio = 1 valorRadio < O. O 7 O, O : valorRadio ) ; 26 27 28 11 devolver el radio 29 public double obtenerRadio 1} 30 { 31 return radio; 32 33 34 11 calcular y devolver el diámetro 35 public double obtenerDiametrol) 36 { 37 return 2 * obtener Radio (}; 38 39 40 // calcular y devolver la circunferencia 41 public double obtenerCirr.unferencial} 42 { 43 return Math. PI * obtenerDiametro 1} ; 44 45 46 // calcular y devolver el área 47 public double obtenerAreal) 48 { 49 return Math. PI * obtenerRadio (} * obtenerRadio 1} : 50 51 52 // devolver la 'epresentación String del objeto Circulo4 53 public String toString 1} 54 {

Figura 9,13 Lo clase circulo4 que extiende a Punta3 y que no proporciona dotas protected. (Parte l de 2.)

copnulo 9 Programación orientada a objetos: Herencia 375

55 56 57 58

return 11 Centro

11 fin de la clase Circulo4

Radio " + obtenerRadio(};

Figura 9.13 La clase Circulo4 que extiende a l?unto3 y que no proporciona datos protected. (Parte 2 de 2,)

En la línea 18, el segundo constructor de Circulo4 ióvoca al constructor de Punto3 (declarado en las líneas 15 u 20 de la ligura 9.12), utilizando la sintaxis de llamada al constructor de la supere/ase: la palabra clave super, seguida por un conjunto de paréntesis que contienen los argumentos del constructor de la su­perdase. Estos argumentos son valorX y valorY, que se utilizan para inicializar a Jos miembros x y y de la superclase. Si el constructor de Circulo4 no invoca al constructor de Punto3 en forma explícita, enton­ces se invoca el constructor sin argumentos de Punto3 en fonna implícita y Java establece las variables x y y en sus valores predeterminados de O. Si la clase l?unto3 no proporciona un constructor sin argumentos, el compilador produce un error, La Humada al constructor de la supcrclase debe ser la primera instrucción en el cuerpo del constructor de la subclase. Use super { l para llamar al constructor sin argumentos de la super­clase en fonna explícita.

_, Error común de programación 9.2 ~ Se pmduce 1m error de compilación si el cmzsrructor de una sube/ase 1/mna a 11110 de los constmctores de .111 Sil·

~ pe1rlau con argumemos qne no com:uerdttll exactamente cmz el mímem y tipos de partimetros especificados en zma de las declaraciones de consrmctor de la superclase.

Observe que cada uno de los métodos obtenerDiametro (figura 9.13, líneas 35 a 38), obtener Area (líneas 47 a 50¡ y toString (lín~as 53 a 56) invocan al método obtenerRadio para obtener el valor d~l radio, en vez de acced¡;r directamente a la variable radio. Si decidimos renombrar la variable de instancia radio, sólo necesitaremos cambiar los cuerpos de los métodos establecerRadio y obtenerRadio.

El método toSt:ring Je !u clase Circulo4 (figura 9. 13, líneas 53 a 56) sobrescribe e1método to­String Je la clase Punto3 (figura 9.12, líneas 47 a 50), La nu~va versión muestra los valores de las varia­bles de instancia pri vate x y y de la clase Punto3 mediante una llamada al método tostring de l?unto3 con la expresión super. toString () (figura 9.13, línea 55). Observe la sinta.xis utilizada para in­vocar, desde una subclase, a un método sobrescrito de la superclase: se colocan la palabra clave super y un punto(.) antes dd nombre del método de la superclase. Esta invocación al método es una buena práctica de in­geniería de software; recuerde que, si un método realiza todas o algunas de las acciones necesarias para otro método, es mejor llamar u ese método en vez de duplicar su código. Al hacer que el método toString de Circulo4 invoque al método toString de l?unto3 para realizar parte de la tarea de devolver la represen­tación de cadena de un objeto Circulo4 (es decir, para mostrar los valores de las coordenadas x y y), se evita que se duplique código y se reducen los problemas de mantenimiento.

1 Error común de programación 9.3 Cuando se sobrescribe un método de la .rupaclase en una subclase, a menudo la ¡•ersión de /a subclase llama a la versión de la supere/ase petra realizar trabajo adicitma/, Si no se anteponen al nombre de/método de lo super-da­se la palabra clave super y 1111 punto (.) cuando se ha~a referencia al método de la superclase, se produce llllo

recur.rividrul injinita, ya que e.l método de la subclase se llamaría entonces a sí mismo.

~ Error común de programación 9.4 ~ Al declarar 1m método publico protected de una supen:/ase con una lista de parámenvs distinta en la snb­[jJJ clase, se oculttl la ¡•ersión de la superclase de ese método, Los imentos por llamar a la versirin de la supere/ase re-

su/tal¡ en errores de cumpilación,

En l¡¡ figura 9.14 se realizan manipulaciones en un objeto Circulo4 de muneru idéntica a lus que se hi­cieron en la Jiguru 9,7, y en la figura 9.11 de las clases Circulo y Circulo3, respcctivruncnte. Aunque cada clase de "círculo" se comporta de manera idéntica, la clase Circulo4 cuenta con la mejor ingeniería. Me­diante el uso de la herencia, hemos construido de manem efectiva y eficiente, una clase con buena ingeniería.

Page 12: 09 - Programacion Orientada a Objetos HERENCIA

376 Programación orientada a objetos: Herencia

11 Fig. 9.14: PruebaCirculo4.java

2 // Prueba de la clase Circulo4.

3 import java.text.DecimalFormat;

4 import javax.swing,JOptionPane:;

5 6 public class PruebaCirculo4

7 8 public static void mainl String[l args 1

9 10 // crear instancia de objeto Circulo

11 12

¡¡ obtener las coordenadas x-y y radio iniciales de Circulo4

String salida " "La coordenada. X es. " + C:i.t9úJ!o::IJR~~he~;,¡J)~ +

"\nLa coordenada Y es " + oifc(hó';¡)fít.'enéYGI• +

"\nEl radio es " + J{Fc¡¡1q¡o·(l~ci!is~l\~Cl~qf// -·

Capijulo 9

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

¡ 1 obtener la representación String del nuevo valor de circulo

salida += "\n\nLa nueva ubicación y radio de circulo son\n" +

¡ ¡ dar form.'lto a los valores de punto decimal con 2 dígitos de px·ecisión

Decirnall'ormat dosDigitos - new DecimalFormat( "0.00" 1;

11 obtener el diámetro del Circulo

salida +=- u \nEl diá.rnetro es u +

dosDigitos.formatl

11 obt:ener la circunferencia del Circulo

salida += 11 \nLa circunferencia es u +

dosDigitos. format 1 8K:Fs\iJ1~:;\'ietim~fq~~s~~re.!7~!i.éJ~L~i1 1;

11 obtener el área de Circulo

salida +" "\nEl área es " + dosDigitos. format 1 ~ff;q'wiKtª~-s~[~~l\!!j~(\¡]1;

JOptionPane. showMessageDialog ( null, salida 1; 11 mostrar :resultados

Systern.exitl O );

11 fin de main

11 fin de la clase PruebaCirculo4

Figura 9.14 Los datos pri vate de la superclase son accesibles para una subclase, mediante los métodos public o protected heredados por la subclase. (Parte 1 de 2.)

capitulo 9 Programación orientada a objetos: Herencia 377

Figura 9.14 Los dolos priva te de la superclase son accesibles para una subclase, mediante los métodos publico protected heredados por la subclase. (Parte 2 de 2.)

,~9.5. Ejemplo práctico: Jerarquía de herencia de tres niveles Consideremos ahora un ejemplo de herencia más subst<mcial, en el que se involucra una jerarquía Punto/Circu­lo de tres niveles. En la sección 9.4 desarrollamos las clases Punto3 (tigura 9.12) y Circulo4 (figura 9.13). Ahora presentaremos un ejemplo en el que derivaremos la clase Cilindro de la clase Circulo4.

La primera clase que emplearemos en nuestro ejemplo práctico es Punto3 (figura 9. 12). Declaramos las variables de instancia de Punto3 como pri vate. La clase Punto3 también contiene los métodos esta­blecerX, obtenerX, establecerY y obtenerY para acceder a ¡e y y, y el método toString para de­volver la representación de cadena de un objeto Punto3.

Ttunbién utiliz:u·emos la clase Circulo4 (figura 9.13), lu cual extiende a la clase Punto3. La clase Circulo4 contiene la funcionalidad de la clase Punto3 y proporciona el método establecerRad:i.o (para asegurar que la variable de instancia radio no pueda guardar un valor negativo) y los métodos obte­nerRadio, obtenerDiarnetro, obtenerCircunferencia, obtenerArea y toString, Las sub­clases de Circulo4 (como Cilindro, que presentaremos en unos momentos) deben sobrescribir estos métodos según sea necesario, para proporcionar implementaciones que seun específicas para lu subclase. Por ejemplo, un círculo tiene un área que se calcula mediante la fórmula 'ilr, en donde r representa el radio del círculo. Sin ~mbargo, un cilindro tiene un Mea supcrficiul que se culculu mediante la fórmula (211'1.2) t (2'ilrlz), en donde r representa el radio del cilindro y h representa su altura. Por lo tanto, la clase Cilindro debe so­brescribir el método obtenerArea, para reflejar este cálculo.

En la figura 9.15 presentamos la clase Cilindro, la cual hereda de la clase Circulo4. La clase Cilindro cspcciika que un Cilindro tiene una altura (línea 5). Los servicios públicos de la clase Cilin­dro incluyen a los métodos establecerRadio, obtenerRadio, obtenerDiarnetro, obtener­Circunferencia, obtenerArea y toString que hereda de la clase Circulo4; los métodos esta­blecerx, obtenerX, establecerY y obtenerY heredados indirectamente de Punto3; los constructores de Cilindro (líneas 8 a 19); y los métodos establecerAltura, obtenerAltura, obtenerArea, obtenerVolumen y toString (lineas 22 a 49) de Cilindro. Los métodos obtenerArea y toS­tring sobrescriben a los métodos con el mismo nombre, que se heredan de la clase Circulo4.

1 // Pig, 9.15: Clli.ndro.java 2 11 Clase Cilindro que hereda de Circulo4. 3 4 5 private double altura; 11 altura de Cilindro 6

Figura 9.15 La clase Cilindro hereda de Circulo4 y sobrescribe el método obtenerArea. (Parle 1 de 2.)

Page 13: 09 - Programacion Orientada a Objetos HERENCIA

378 Programación orientado o objetos: Herencia Ccpijulo 9

7 11 constructor sin argumentos 8 publlc Cilindro() 9 {

10 11 12 13 // constructor 14 public Cilindro( int valor)(, int valorY, doubl.e valorRadio, 15 double valorAltura ) 16 17 ~JtP:e~J¡y~~a.t7x~;ya?;9lxt;;@~\:lí:'R~~~a; Y:¡,¡ 2:3 .U~!Jl.'B; §1)i;Cfr::~r~m;t;?,ri'q~~tfi;~~19~ 18 establecerAltura( valorAltura ); 19 20 21 1/ establecer la altura del Cilindro 22 public void establecerAltural double valorAltura 23 { 24 altura ~ ( valor Altura < O. O 7 O. O : valorU tura ) ; 25 26 27 11 obtener la altura del Cilindro 28 public double obtenerAltura() 29 { 30 return altura; 31 32 33 ¡¡ sobrescribir al método obtenerArea de Circulo4 para calcular área del Cilindro 34 public double obtenerArea 1) 35 { 36 return 2 • $~P~~ ~gp~[,;M~fi!::í:':{:II + obtenerCircunf<;renc.ia 1) * obtenerAltura (); 37 38 39 11 calcular el volumen del Cilindro 40 public double obtenerVolumen() 41 { 42 return ~)l~~e:(üilitJ!ri,~~~it~~[l! * obtener Altura 11; 43 44 45 // devolver la representación String del objeto Cilindro 46 public String toString () 47 { 48 ~§klifu:~~üj;jff,:;t:.2%@~fut.tl + "; Al tu~: a " ' obtener Altura 1) ; 49 50 51 11 fin de la clase Cilindro

Figura 9.15 La clase cil.indro hereda de Circulo4 y sobrescribe el método obtenerArea. (Parte 2 de 2.)

El método obtenerArea (líneas 34 a 37) sobrescribe el método obtenerArea de Circulo4 para calcular el área superficial del cilindro, El método toString (líneas 46 a 49) :;obrescribe el método to­String de la clase Circulo4 para devolver lu representación String del cilindro. La clase Cilindro también declara el método obtenerVol umen (líneas 40 a 43) para calcular el volumen del cilindro.

En la Ji gura 9.16 se muestra una aplicación llamada PruebaCilindro que prueba la cluse Cilindro. En la línea 11 se crea una insumcia de un objeto Cilindro llamado cilindro. En las líneas 14 a 16 se uti­lizan los métodos obtenerX, obtenerY, obtenerRadio y obtenerAltura de cilindro para

capffulo 9 Programación orientado e objetos: Herencia 379

obtener información acerca de este objeto, ya que PruebaCilindro no puede acceder directamente a las va­riables de instancia priva te de la ciase Cilindro. En las líneas 18 a 21 se utilizan los métodos estable­ce:rX, establecerY, establecerRadio y establecerAl tura para restablecer las coordenadas x-y de cilindro (suponemos que las coordenadas .1-y del cilindro cspecitican la posición del centro de su parte inferior, en el plano x-y), su radio y su altura. La clase Cilindro puede utilizar los métodos establecerx, obtenerX, establecerY y obtenerY, ya que la cluse Cilindro los hereda indirectamente de la clase punto3. (La clase Cilindro hereda los métodos establecerX, obtenerX, establecerY y obtenerY directamente de la ciase Circulo4, que a su vez los hereda directamente de la clase J?unto3.) En las líneas 24 a 26 se invoca el método toString de cilindro para obtener la representación String del objeto cilindro. En las líneas 32 y 33, y en las líneas 36 y 37 se invocan los métodos obtenerDiametro y obtenerCircunferencia, respectivamente, del objeto Cilindro (como la clase Cilindro hereda los métodos de la clase Circulo4, se invocan estos métodos, exactamente como se declararon en Circulo4), En ]as líneas 40 a 43 se invocan los métodos obtenerArea y obtenerVolumen, respectivamente, para obtener el área superficial y el volumen del cilindro. En la línea 45 se muestra la cadena resultante.

1 2 3

11 Fig. 9.16: PruebaCilindro.java 11 Prueba de la clase Cilindro. import java. text.DecimalForma;;;

4 impo¡ct; javax. swing. JOptionPane; 5 6 7 8 9

10 11 12 13 14

public class PruebaCilindro

public static: void rnain( String[] args ) {

11 obtener las coordenadas x-y, radio y altura iniciales del Cilindro String sallda ~ "La coordenada

15 "\nLa coordenada Y es • ,, ~tl:~~rtgl:'q\!l!l~M'erY

16 :q~~i'\ld#{o~l:;·;oB?.,r~~ª~'U)' + Fc~,I:i:[\s\rR;•,'')JJ';i'l'fPI\tl#·~,(¡),i;, 17 18 19 20 21 22 23 11 obcener la representación String del nuevo valor de cilindro 24 salida +"

25 "\n\nLa nueva ubicación, radia y altura del cilindro son\n" +

26 :9,UL~nS!to':~tg~t:~~J.n~JJl; 27 28 11 dar formato a los VOtlares de punta flotante con 2 dígitos de precisión 29 DecimalPormat dasDigitos = new DecimalFormat ( "O. 00" ) ; 30 31 11 obtener el diámetro del Cilindro 32 salida += "\n\nEl diámetro es " ~ 33 dosDigi tos. format 1 g~A~9~íli6i.5t@i;_ti¡~ª!ff~~~9Ií! ) ; 34 35 11 obtener la circunferencia del Cilindro 36 aalida + ~ "\ nLa circunf arencia es " + 37 doaDigitos. rorrnat ¡ ªB::'~Tifl.tli~í?lj;~~il&~~;t'ííSiJ.l~~~!!~Bil!Hm l; 38

Figura 9.16 Programa de prueba para la jerorqulo Punto/Circulo/Cilindro. (Parte 1 de 2.)

Page 14: 09 - Programacion Orientada a Objetos HERENCIA

380 Programación orientada a objetos: Herencia Capijulo 9

39 40 41 42 43 44 45 46 47 48 49 50 51

/1 obtener el área del Cilindro salida +• "\nEl área es " + dosDigi tos. formal: 1 t;JI~'A\lf.~J\i.J?~¡j~1J.~'/l~:~-%T~ 1 ;

1 í obtener el volwnen del Cilindro salida+= "\nEl volwnen es " + dosDigitos. format 1 t¡g~h~~q¡;&\i~~@'¿:ó}l~ffi~nlJ.l 1;

JOptionPane. showMe8sageDialog ( null. salida 1; 11 mostrar resultados

System.exit( O 1;

í 1 fin de main

11 Ein de la clase PruobaCilindro

Figura 9,16 Programa de prueba para la jerarquía Punto/Circulo/Cilindro, (Parte 2 de 2,)

Utilizando el ejemplo Punto/Circulo/Cilindro, hemos demostrado el uso y los beneficios de la herencit\. Pudimos desarrollar las clases Circulo4 y Cilindro con mucha mayor rapidez mediante el uso de la he­rencia que si las hubiéramos desarrollado "desde cero". La herencia evita la duplicación de código y los pro­blemas de mantenimiento de código asociados.

9.6 Constructores y finalizadores en las subclases.: Como explicamos en la sección anterior, al crear la instancia del objeto de una subclase se genera una cadena de llamadas a los constructores, en donde el constructor de la subclase, antes de realizar sus propias tareas, in­voca u! constructor de su supcrclase directa, ya sea en fom1a explícita (mediante la referencia super) o implí­cita (llamando al constructor predeterminado de la superclase, o a su constructor sin argumentos). De manera similar, si la supercluse se deriva de otra clase, el constructor de la superclase tiene que invocar al constructor de la siguiente clase que esté un nivel aniba en la jerarquía, y así sucesivamente. El último constructor llama­do en la cadena siempre es el constructor de la clase Obj ect. El cuerpo del constructor de la subclase origi­nal termina de ejecutarse en último lugar. Cada uno de los constructores de la superclasc manipula a las varia­bles de instancia de la superclase, las cuales son heredadas por el objeto de la subclase. Por ejemp\o, considere de nuevo la jerarquía Punta3/Circulo4/Cilindro de las tíguras 9.12. 9.13 y 9.15. Cuando un programa crea un objeto Cilindro, se realiza una llamada al constructor de Cilindro. Ese constructor llama al cons­tructor tle Circulo4, el cual a su vez llama u! constructor de Punto3. El constmctor de Punto3 llama al constructor de Obj ect. El constructor de la clase Obj ect tiene un cuerpo vacío, por lo que devuelve inmediata­mente el control u! constructor de Punto3, el cual manipula entonces las coordenadas x-y del objeto Cilindro. Cuando el constructor de Punto3 termina de cjccuwrse, devuelve el control al constructor de Circulo4, el cual manipula el radio del objeto Cilindro. Cuando el constructor de Circulo4 termina de ejecutarse, devuelve el control al constructor de Cilindro, el cual manipula la altura del objeto Cilindro.

capftulo9 Programación orientada a objetos: Herencia 381

Observación de Ingeniería de software 9.4 ril Cuando 1111 programa crea elobjew de ~~~~~subclase, el cmwructor de la ;:1bcl~~e llama in.mediatameme al cvns· ~ tmctor de ltt supere/ase (en forma expltcua medtante super, v en jorma tmpilcua), El cut•rpv del constructor de

la supere/ase se ejecuta para manipular /lis variables de instancia de la supere/ase, y el cuerpo del constructor de /a subclase se ej¡!r:utct para manipular las variables de instancia de la sube/e¡ ve. Java se asegura de que wdas las vuriables de ilwanda se inicialicen cm1 sus valores predetem1i11ados. Por lo Ja¡¡to, aunque un constructor no asigne 1111 valor n 111/CI variab/t! de instancia, la variable se inicializll de todas forums.

Si lus dases en su jerarquía de clases tienen sus propios métodos finaliza, el método finalize de la subclase debe invocar al método finaliza de la superclase como su última acción, para asegurar que to­das !;1s partes de un objeto se 1inaliccn apropiadamente en caso de que el recolector de basura reclame la me­moria de ese objeto. Cuando se llama al método finaliza de un objeto de la subclase, este método realiza su tarea y luego debe invocar al método finalize de la siguiente superclase en la jerarquía. Este proceso debe repetirse hasta que se llame al finalizador de la superclase Obj ect. Después la memoria se vuelve dis­ponible para ser utilizada por nuevos objetos.

En nuestro siguiente ejemplo utili~aremos nuevamente la jerarquía Punto/Circulo, declarando una nueva clase Punto (figura 9.17) y una nueva clase Circulo (figura 9.18). Cada una de estas clases dedaru cons­tructvres y métodos finaliza, los cuales imprimen mensajes al ser invocados.l

La clase Punto (figura 9.17) contiene las mismas características que la versión de la clase que se mues­Ir.! en la figura 9.4. Modificamos los constructores (líneas 9 a 13 y 16 u 23) y agregamos un método finali­ze (líneas 26 a 29). Cada uno de ellos imprime una línea de texto en la línea de comandos. al momento de su invocación. Observe la concatenación de this con una cadena en las líneas 12, 22 y 28, en la cual se invoca implícitamente el método toString del objeto para obtener la representación de cadena de ese objeto.

1 2 3

// fig. 9.17: Punto.java 11 La declaración de la clase Punto representa un par dr; coordenadas x-y,

4 public class Punto 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

pri vate int: Xí private int Yí

/i parte x del par de coordenadas /1 parte y del par de coordenadas

11 constructor sin·argumentos public Punco 1 i {

1/ la llamada implí.cita al constructor de Object ocurre aquí

/1 constructor public Punto( int valorX, int valorY 1 {

11 la llamada implícita al constructor de Object ocurre aquí x valorXí /1 no hay necesidad de validación y • valorY; /1 no hay necesidad de validación

Figura 9.17 La superclase Punto contiene dos constructores y un finallzador. (Parte 1 de 2.)

l Al igual que en la sección ~.11, utiliz:¡mos el método finaliza en este ejemplo sólo pnru mostrar cuándo el recolector de basura remueve un objeto de la memoria. Gonorahnente no se recomienda el uso de finaliza.

Page 15: 09 - Programacion Orientada a Objetos HERENCIA

382 Programación orientada a objetos: Herencia

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

11 cestablecer x en el par de coordenadas public vcid establecerXI inc valorX ) (

¡: : valor X; 11 no hay necesidad de validación

11 devolver :< del par de coordenadas public int obcenerX 1) 1

.return x;

11 establecer y en el par de coordenadas public void establecerYI int valorY 1 {

y : valor'{; // no hay necesidild de validación

11 devolver y del par de coordenadas public int obcenerYII {

return y;

11 devolvr;r la representación String del objeto Punto public String toString 11

rr;turn '' [" + obtener X 1) + • + obtenerYI) • "]";

11 fin de la cl.>se Punto

Figuro 9.17 La superclase Punto conffene dos constructores y un ñnallzador. (Parte 2 de 2.)

Capítulo9

La clase Circulo (figura 9.18) contiene lus características de la clase Circulo4 (figura 9.13), Moditi­camos los constructores (líneas 9 a 13 y 16 u 22 de la figura 9.18) y agregamos un método finalize (figu­ra 9. 18, líneas 25 a 30). Cada uno de ellos imptime una línea de texto en la línea de comandos, al momento de su invocación. De nuevo, observe la concatenación de this con una cadena en las líneas 12, 21 y 27 para ob­tener la representación de cadena del objeto.

1 2 3

11 Fig, 9.18: Circulo.java 11 Declaración de la clase Circulo.

4 public clasa Circulo extends Punto { 5 6 7 8

private double radio; 11 el radio del Circulo

/1 constructor sin argumentos

Figura 9.18 La clase Circulo que extiende a Punto. (Parte 1 de 3.)

capffulo 9

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 5ó 57 56 59 60 61 62 63

public Circulo 1) {

Programación orientada a objetos: Herencia 383

11 la llamada irnpHcita al constructor de Punto ocurre aquí

1/ constructor public Circulo 1 int valorX, int valor Y, double vi1lorRadi.o ) (

super 1 va lorX, valorY 1; 11 llamar al constructor de Punto establecerRadiol valorRadio );

1/ establecer el radio public void establecerR,>dio 1 double valorRadio 1 {

radio~ 1 valorRadio < 0.0? 0.0 : valorRadlo 1;

11 de vol ver el radio -publlc clouble obt:enerRadio 11 {

return radio;

11 calcular y devolve¡· el diámetro public double obtenerDiametroll (

return 2 * obtenel·Radio 11 ;

/1 calcular y devolver la cücunferenda public doubl8 obtenerCircunferencia 11 {

return Math.PI * obtenerDiametroll;

11 calcular y de vol ve1· el área public double obtener.~¡:ea 11 {

return Math. PI * obtenerRadio 11 * obtenerRaclio 11;

( 1 deyol•rer la representación St.ring del objeto Circulo public Stüng to.Str.lng 1)

Figura 9.18 La clase Circulo que extiende a Punto, (Parte 2 de 3.)

Page 16: 09 - Programacion Orientada a Objetos HERENCIA

384 Programación orientada a objetos: Herencia

64 65 66 67 68

return "Centro " + super. toString ( 1 + ";

11 fin de la clase Circulo

Figura 9.18 La clase Circulo que extiende a Punto. (Parte 3 de 3.)

1 // Fig. 9.19: PruebaConr.tructorFinalizador. java

Capfiulo 9

Radio ' + obtenerRadio();

2 // Huest¡:a el orden en que se hacen las llamadas a los constructores 3 // y Einalizadoren de la superclase y la subclase. 4 5 public class Prueb.'!ConstruccorF lnalizador 6 7 publlc static void main( String args[] a 1 9 Punco punto;

10 Circulo circulol, circulo2; 11 12 ~ünt<i ~ne1.J 13 14 15 16 17 Sys tem. out. println ( 1 ; 18 19 20 21 22 23 24 System.out.println(); 25 26 27 28 11 fin de main 29 30 11 fin de la clase PruebaConstructorFinalizadOl"

Figura 9.19 Orden de la llamada a un constructor y a un ffnalizador.

Programación orientada a objetos: Herencia 385

En la ti gura 9.19 se muestra el orden en el que se hacen las llamadas a los constructores y finalizadores pura los objetos de clases que fonnan parte de una jerarquía de herencia. El método main (líneas 7 a 28) em­pieza creando la instancia de un objeto Punto (línea 12). Después. en la línea 15 se crea la instancia de un objeto Circulo llamndo circulo l. Esta acción invoca al constructor de Punto para que impdma un men­S<\je con los valores que recibe del constructor de Circulo, y después se imprime el mensaje especificado en el constructor de Circulo. En la línea 18 se eren la instancia de un objeto Circulo llamado circulo2. De nuevo, se hace unu llamada al constructor de Punto y otr¡1 al constructor de Circulo. Observe que, en cada caso. el cuerpo del constructor de Punto se ejecuta antes que d cuerpo del constructor de Circulo.

En las líneas :w a 22 se establecen punto, circulol y circulo2 en null. Los objetos a los que es­tas variables hacen referencia ya no son necesarios en el programa, por lo que Java mnrca a estos objetos para la recolección de basura. Java garantiza que, antes de que el recolector de basura se ejecute para reclamar el es­pacio tle cada uno de estos objetos, se hm·án las llamadas a los métodos finalize para cada objeto. No obs­tante, recuerde que en la sección 8.10 vimos que no se garantíza cuándo se ejecutará realmente el recolector de basura. Por esta razón, invocan1os al método estático gc de la clase System en la línea 26. Java no garantiza el orden en el que el recolector de basura reclamará Jos objetos; por lo tanto, no puede garantizar cuál de los finalizadores se ejecutará primero. Cuando se realiza la llamada al método System. gc, se realizan las lla­madas a los finalizadorcs de los objetos punto, circulol y circulo2. El finalizador de Circulo y el finalizador de Punto son llamados (en ese orden) para el objeto circulol, y los tinalizadores de Circulo y Punto se llaman (en ese orden) para el objeto circulo2. (Nota: El método finalize de la clase Object no hace nada, por lo que no lo llmnamos desde el método finalize de la cla¡;e Punto.)

-:~9.71ngeniería de software mediante la herencia ~o

En esta sección hablaremos sobre la personulización del software existente mediante la herencia. Cuando una nueva clase extiende a una clase existente, la nueva clase hereda los miembros no priva te de la clase exis­tente. Podemos personalizar la nueva clase para que se adapte a nuestras necc~;idades, incluyendo miembros adicionales y sobrescribic¡1do los miembros de la superclase. Esw se hace en Java sin necesidad de que el programador de la subclase tenga que modificar el código fuente de la Sllperclase. Java simplemente requiere acceso al archivo . class de la 1:uperclase, de manera que pueda compilar y ejecutar cualquier programa que utilice o extienda a In superclasc. E1:ta poderosa capacidad es atrnctiva para los fabdc;mtes independientes de sortware (JSVs), que pueden dcsarrollm· clases propietarias para vender o licenciar. y poner a disposición de los usuarios esas clases en formato de código objeto. De esta forma, los usuarios pueden derivar nuevas clases de estas bibliotecas de clases con rapidez y sin necesidad de acceder al código fuente propietario de los ISV s.

En oc:wioncs es difícil para los estudiantes apreciar el alcance de los problemas a los que se enfrentan los diseñadores que trabajan en proyectos de software de gran escata en la industria. Las personus que tienen ex­periencia en esos proyectos dicen que la reutilización efectiva de software mejora el proceso de desan·oJlo del mismo. La programación orientada a objetos facilita la reutilización del software, reduciendo en consecuencia el tiempo de desarrollo.

La disponibilidad de bibliotecas de clases substanciales y útiles produce los máximos beneficios de la reu­tilización de software a través de la herencia. El interés en las bibliotecas de clases csuí creciendo en forma cxponcnciul. Al igual que las pequeñas versiones de software producidas por los ISVs se convirtieron en una industria de crecimiento explosivo con la llegada de la computadora personal, así también sucedió con la crea­ción y venta de bibliotecas de clases. Los diseñadores de aplicaciones construyen sus aplicaciones con estas bibliotecas, y los diseñadores de bibliotecas son recompensados al tener sus bibliotecas incluidas con las apli­caciones. Las bibliotecas de clases estándar de Java que se incluyen con la J2SE 1.4.0 tienden a ser de propó­sito general. Sin embargo, existe un compromiso mundial musivo en cuanto al desarrollo de bibliotecas de clases para una enorme variedad de aplicaciones.

~ Observación de ingeniería de software 9.5

~ En la etapa de dise1io de un sistema oriemadu a objetos, el dise~im/or a menudo encuentra que ciertas clase.¡ es­~ Lán íntimameme relacionadas. El di.\"éliodor debe "resallar" las mributo.v y comportamientos comunes, y colocar­

lo.¡ en una .wperc/a.ve. Entonces, el diseliador dehe ulilizar la lm~ncia para desarrollur subclases, ororgdndo/es rapacidade.\· mds allá de las que se hereden de la supere/ase.

Page 17: 09 - Programacion Orientada a Objetos HERENCIA

386 Programación orientada a objetos: Herencia

. Observación de ingeniería de software 9.6 ~~ El proceso de declarar una subclase no q{ecra al código fuente de su supere/ase. La herencia pre.1wva La integri. ~dad de una Sllperc/ase.

Observación de ingeniería de software 9.7

¡'~ ~sí como Losdlmiadar;s de sistema~ 110 orietztados <! o~¡erus d~ben::vitar una prolij'eración rle.métud~s, Los dise. ~ nadares de s¡stemas onentadas a ob;<•tos dt•ben evttar fu pmlijemcwn de lus clases. E.1·ta proli[rmcwrz cn•a pro.

blemas ctdministrlllivos y puede dijicu/tar La n•wi/ización d<• software, ya que al clieflle se le dijiculta localizar la clase m<Ís apropiwla en una enorme biblioteca dt~ clases. La allemativa e,¡ crear lllt!rws clases qll<' proporcionen una jimcionalidud nuís substancial, pero dichas clases podríun 1/egor a pmveer demosiatla jlowionalídacl.

Tlp de rendimiento 9.1 Q Si /a.v subclases svnmds grandt•s de lo necesario (es decir, qU<' contengan cleuwsiada jimcionalidacl), los recursos ~de memoria y de procesamienll/ podrzim de.>padiciarse, Extienda la clase con la ftmciorwlidad que se "aproxime

mds" a /u que se necesita. ·

Leer las declaraciones de lus subclases puede ser algo confuso, ya que los miembros heredados no se de. ciaran en fonna explícita en las subclases, pero son miembros de ellas. Un problema similar existe al tratar de documentar los miembros de la subclase.

En secciones anteriores presentamos la herencia (la habilidad de crear clases absorbiendo los miembros de una clase existente y embelleciéndolos con nuevas capacidades). En el capítulo LO nos basaremos en nuestra discusión acerca de la herencia para presentar el polimiJijismo (un concepto orientado a objetos que nos p~nni. te escribir progrumas que manejen, de una manera más general, una amplia variedad de clases relacionadas por la herencia). Después de que estudie el capítulo 1 O, estará familiarizudo con lus clases, el encapsulamiento, la herencia y el polimorfismo (los aspectos más cmciales de la programación orientada a objetos).

RESUMEN • Lu reutilización de software reduce d tiempo de desu!Tollo de los programas. • La soperclase direcu¡ de tma subclase es la supere! ase de lu cual hereda (se especifica mediunte la palabra clave extends

en la primem línc;t de una declaración de clnse). Unu superclasc indirecta de una subclase se encuentm ¡¡dos n mds ni· veles h¡¡ciu arriba de distancia de esa subcla,;c, en la jerarquía de clases.

• En la herencia simple, una clase se deriva de una supcrclasc directa. En la herencia múltiple, una dase se deriva de mús de una ~upcrclasc directa. Java no cuenta con soporte para la herencia múltiple.

• Una subclase puede declarar a sus propios miembros (variables de instancia y métodos), por lo que una subclase es a me· nudo m;b grande que su superclase.

• Una subclase es más espccílica que su superclase y representa a un grupo más pequeño de objetos. • Todo objeto de una 1:ubclase es rambién un objeto de la supcrclase de esu clase. Sin embargo, un objeto de una supercla·

se no es un objeto de las subda1es de esa clase. • Una relación ''es un" representa la herencia. En este tipo de relación, el objeto de una subcla1c puede tratarse también co­

mo un objeto de su nuperclase. • Una relación "tiene un" representa la composición. En este tipo de relación, el objeto de una clase contiene referencias a

objetos de otras clases. • Una subclase no puede utilizar ni heredar los miembros pri vate de su superclilSe; si se permitiera esto se quebranta·

ría el encapsulamiento de la superclasc. Sin embargo, unu subclase puede heredar los miembros public y protacted de su superclase. ·

• Ctumdo el método de una superclase es inapropiado para una subclase, ese método puede sobrescribirsc en la subcla1e mediante una implementaci6n apropiada.

• Las relaciones de herencia simple forman estmcturas jerárquicas tipo •írbol; una supere! ase existe en una relación jcrár· quica con sus subclases.

• Los miembros public de una superclase son accesibles en cualquier parte en donde el progruma tenga una referencia u un objeto de esa superdase, o u un objeto de una de hu; subclases de esa superclase.

• Los miembros pri vate de una supercluse son aCCl'sibles solwnente dentro de lu declaración de esa supere! ase. • Los miembros protected de una superclase tienen un nivel intennedio de protección entre el acceso public y el nc·

ceso priva te. Los miembms protected de una !JUpcrcluse pueden ser utilizndos por los miembros de esa supercla· se, y heredados por los miembros de cualquier cluse derivada de esa superclase.

cap~ulo 9 Programación orientado a objetos: Herencia 387

, Cuando el método de una subclase sobrescribe al método de una superclilSe, el método de In superclase puede utilizarse desde la subclase si se wttepone al nombre del método de la superclasc la palabra clave super y un punto(.).

, Al dedar;U' las vmiables de instancia como pri vate y proporcionar al mismo tiempo métodos no pri vate para ma­nipular y rcaliztU' la comprobación de vulidc¡, se retizcmtla buena ingenierín de software.

, El método toString no tomu argumentos y devuelve un String. El método toString original de ht clase Object sirve para gtuu·dar lugar, y generalmente se sobrescribe en unn subclase.

, Al concatenar lUla cadena con cuulquier objeto se produce una llnmuda implícita al método toString de ese objeto, pura obtener unu representación \le cadena de un objeto, y después se concatcnnn las cadenas.

TERMINOLOG{A ubstrJcción biblioteca de cltL~cs composiciún constructor de una subclase constructor de una superclasc constructor sin argumentos de una

superdase constructor sobrecargado control de acceso diagrama jerárquico e¡¡tenda linalizador de una subclase linalizador de una supcrci;LIC herencia herencia múltiple herencia simple lnvncar al constructor de una

supere Jase invocar al método ~ohrescrito tic una

supere! ase

ISV (f;tbricante independiente de software)

jerarquía de clases jerarquía de herencia método heredado miembro heredado miembro priva te de una

supere! ase miembro protected de una

supcrclasc miembro public de una

supere! ase Obj ect. clase objeto de una subcla~e objeto de una superclase ocultamiento de infonnación POO (progrumm;ión orientada u

objetos) protected, palabra clave recolección de basura

EJERCICIOS DE AUTOEVALUACIÓN 9.1 Complete las siguientes owciones:

referencia a un objeto de una su helase

referencia u un objeto de una superclase

relación es 1111

relación jenírquica relación tiene un reutilizacitÍn de software sobrescribir el método de una

superclase subclase super superclase superclase directa superclase indin:cta toString, método de la clase

Object variable de instuncia heredada

a) es una forma de reutilización de software, en lu que nuevas clases adquieren Jos datos y eom· portmnientos de las clases existentes, y se mejoran o;on nuevas capacidades.

b) Los miembros de una superchLse pueden utilizarse solamente en la declaración de ht supcrcla· se o pueden ser heredados por las subchu;es.

e) En una relación , un objeto de unu subclilSe puede ser tratado también como un objeto de su superdase.

d) En una reh1ción , el objeto de unn clase tiene referencia~ a objetos de otras cltu;es como miembros. e) En la herencia simple, una clase existe en una relación con sus subcluscs. f) Los miembros de una superclase son accesibles en cualquier pune en donde el programa tenga

una referencia a un objeto de esa supcrclase, o a un objeto de una de sus subclases. g) Los miembros de ;tcccsQ protected de una superclase tienen un nivel de protección entre los miembros de

acceso y los de acceso -----h) Cuando se creu la instancia de un objeto de una subchu;e, el de una supcrclilSe se llama en for·

mtt implícita o explícita. i) Los constructores de una subcla1e pueden IJ¡mtw· a los constructores de la superclase mediante la palubm clave

9,2 Conteste con verdadero o falso a cudu una de las siguientes proposiciones; en caso de ser fulso, explique por qué, a) Es posible trntar ttlos objetos de una supcrclase y a los objetos de unu subclase de mancrn similar. b) los constructores Je la .~upcrclasc no son heredados por las subclases. e) Una relación "tiene un" se implementa mediante In herencia. d) la clase Auto tiene una relación "es un" con su VolanteDireccion y sus Frenos. e) la hercnuia fomenta la reutilización de software comprobado, de alta calidad.

Page 18: 09 - Programacion Orientada a Objetos HERENCIA

388 Programación orientada a objetos: Herencia Copftuio9.

l) Cuando una subclase redetlnc al método de una superclase utilizando la misma tirma, se dice que la subclase sobrecarga a ese método de lu superclase.

RESPUESTAS A LOS EJERCICIOS DE AUTOEVALUACIÓN 9.1 a) Herencia. b) protected. e) "Es un" o de herencia. d) "Tiene-un", o composición o agregación.

e) Jerárquica. f) public. g) public, priva te. h) Constructor. i) super.

9.2 a) Verdadero, b) Verdadero. e) Falso. Una relación "tiene un" se implementa mediante lu composición. Una relación ·'es un" se implementa mediante la herencia. d) Falso. Éste es un ejemplo de una relación "es un". La clase Auto tiene unu relación "es un" con la clusc Vehiculo. e) Verdadero. t) Falso, Esto se conoce coma sobrescritura, no sobrecarga.

EJERCICIOS 9.3 Muchos programas escritos con herencia podrían escribirse mediunte la composición, y vicevcma. Vuelva a escri­

bir las clases Ciraulo4 (figura 9.13) y Cilindro (ligum 9.15) de la jerarquía Punto3/Circulo4/Cilindro, para usar la composición en vez de la herencia, Una vez que haga esto, valore los méritos relativos de lus dos me­todologías para los problemas del Punto3. Circulo4 y Cilindro, así como también para los programas orientados !l oh jetos en general. ¿Cuál metodología es más natural? ¿Por qué?

9.4 Algunos programadores prdieren no utilizar acceso proteatcd. ya que creen que quebranta el encapsulamien­to de la supercluse. Hable sobre los méritos relativos de utilizar acceso protected, en comparación con utilizar el :¡cceso priva te en las superclases,

9.5 Vuelva a escribir el ejemplo práctico de la sección 9.5, como una jerarquía Punto/Cuadrado/Cubo. Haga es­to de dos formas: una mediante la herencia y una mediante la composición.

9.6 Escriba una jerarquía de herencia para las clases Cuadrilatero, Trapezoide, Paralelogramo, Rectan­gula y cuadrado. Use Cuadrila tero como la superclase de la jerarqufa. Haga la jerarquía con todos los ni­veles que sea posible. Especifique las variables de instancia y los métodos para cada clase. Los datos pri vate de Cuadrilataro deben ser los pares de coordenadas x-y para las cuatro esquinas del Cuadrilatero. Escriba un prot,'!'mna para instanciar objetos de sus clases y que muestre el ilrea de cada objeto (excepto Cuadrilatero).

9.7 Anote todas las figuras en las que pueda pensar (tanto bidimensionales como tridimensionales) y ordene esas ti­guras en unajerarqu(a de tigurus. Sujeran¡ufu debe tener la clase Figura en la purte superior. Las cla.1es Figu­raBidimenaional y FiguraTridimensional deben extender a Figura. Una vez que huya dcsmTol!ado la jerarquía, declm·e a cada una de las clases en ella. Utilizaremos esta jerarquía en los ejercicios pura procesar to­das las liguras como objetos de la superclase Figura.

9.8 Cn:e las clases que se encuentran en la jerarquía de herencia de la ti gura 9.20. Un Empleado debe tener un primer nombre, apellido patcmo y número de seguro social. Además, un EmpleadoMalariado debe tener un salario semanul; un EmpleadoPorHoraa debe tiene un sueldo y el número de horas trabajadthl; un EmplaadoPor­Comision debe tener una tasa de comisiones y ventas brutas; y un EmpleadoBaaeMasComision debe tener un s:tlario base. Cada clase debe tener los constnictores apropiados, los métodos establecer y obtener, Escriba un programa que cree instancias de objetos de cada una de estas clases, y que muestre toda la información asociada con cadu objeto (incluyendo la información hereduda).

''·,,

[~~~E~~I!~rá~,'

Figura 9.20 Jerarquía de herencia de Empleado.

Programación orientada a objetos:

Polimorfismo

, Comprender el concepto de polimorfhano.

, Aprender a utilizar métodos sobrescritos para llevar a cabo el polimorfismo.

, Distinguir entre clases abstractas y concretas.

• Aprender a declarar métodos abstract para crear clases abstractas.

• Apreciur la manera en que el polimorfismo hace que Jos sistemas puedan extenderse y mantenme.

• Determinar el tipo de un objeto en tlcmpo de ejecución.

Un anillo pam gobernar/os a rodas, un anillo para encontrarlo;·, Un anillo para traerlos a todos y en la oscuridad enlazarlos. John Ronald Rcuel Tolkien

Las proposiciones generales no ch•ciden casos concretos. Oliver Wendell Holmes

Un filósofo de imponente estatura no piensa en un vacío. Incluso sus ideas más abstractos son. en cierta medida, condicionadas por lo que se conoce a no en el tiempo e11 que vive. Alfred North Whitchcad