Herrencia y Polimorfismo
Herrencia y Polimorfismo
Herrencia y Polimorfismo
xra dr
rchir.o
los
de
s. ivl Uesfe
in
la po_
s despus
re mucha
:1 mismo o.
Flerene ia y polimcfl'fisrno
:ograma. ;iguiente
0b,i etEvos
Despt;: de leer;' cstuCiar cslc ccpt:.;lo, usted tje be r
e,
--Ec
ib,i
p t9g
r:
rn
as que. s ea f ci I m e n te'
o Diferenciar
pnotected.
sn
1-.,.,:;.,'i':.i,:',ill;..,llt1.f::.,'-'";; ;'....:.:::.';.|.'1::..:::.l|.:::i:]].::]:.:.j]:.
r'. '
'-;'-iiLrl.lrlt_:.1i
fi
':i:i.11:..'ri:i,:
.r.
...
.
. :..
,,,i':.,:
,.
713
714
Captuo
13
Herencia y polimorfismo
lntroduccn
polimorfismo
::ngt:::',#"*adores
cin orienrada a objeros: ra herencia 9e la programa_ p"l1-"rn.*o. n'";;;;r," l | se inrodujo caracierstica herencia de ia programcin "r orientada ra a objetos.-g"r," captulo propor_ cionaremos una expricacin ms=detallada y ejempros de n"r*"iuEl segundo tema ms importanre qu" ." uuo.oia *i" ,"prn iL x erpolbnrfis., que constituye offa caracterstica funamental A" iu "" p.og;;;;;' enviar el mismo *"^"r-J a oo;etos
llffittnH:
6L
Esto ind
Gato
(
cuent.a . calcuLaCuotaMensual
),.
sub<
N
mensaje
polimrfico
fico
oL o$m c'elm* ques' entonces se ejecutar el mtodo calculcuotaMensual "u"ot" d.fi rffi cuentacheques' En consecuencia, enviar el mensaje podra oarporlesnraao helmifo de diferentes mtodos. El mensaje calculacuotaMensuar se denomina la:4&,i
porque dependiendo del objeto receptor, se ejecutan dir,"oo,
donde cuenta puede ser un objeto cuentaAhorro o rm objeto cuenffireqrx" si es un objeto cuentaAhorro, entonces se ejecutar el mtodo carcutaG.otallerrsd do para la clase cuentaAhorro. De semejante,
osn
gbclase superclase
**
",
ficil
de modifrca
-todoo
a pdin-
"ir""L
En este
.--r$
ffi'ne
class Mascota{ private String nombre; public Strj_ng obtenNombre( ) { return nombre;
1
nombreMascota)
utiliza la clase:
ilqr#i
t3.l Unelrnfloinpb
7lJ
Hay muchos tipos de mascotas diferentes, de modo que realmente nolodennesperr" que una clse pueda modelarlos a todos. Todo mundo sabe cuntos perros, gabs yrcfohs distintos hay, por ejemplo. Definiremos las clases individuales Gato y perro paramoddrlas de manera ms precisa que la clase genrica Mascota. Luego, envezde definirlas dm nuevas clases independientemente, los definiremos con base en la clase Mascota. Armqrrc son diferentes, comparten la caracterstica comn de ser mascotas, de modo que tiene sentido deducir ambas clases a partir de la clase Mascota. Esto es herencia. Haremos que las clases Perro y Gato hereden los miembros de datos y mtodos de la clase Mascota.
subclase de
Mascota
cLass Gato extends Mascota { public Strj-ng habla ( ) { return tNo me des rdenes. \n', + 'Hblo slo cuando quiero. )
I
'r ;
):
La clase Gato se denomina subclase o clase derivada, y la clase Mascota se denomina superclase oclase base.Patadefinirunasubclaseseulizalapalabrareservadaextends. Los miembros de datos y mtodos de una superclase son heredados por sus subclases. As, por ejemplo, el siguiente cdigo es vlido:
System.out.prinlln("HoIa, mi nombre es rt +
miGato,obtenNombre O ) ;
;A:i
En la clase Gato, se observa que el cuerpo del mtodo habla es diferente. Decimos que la clase Gato redefine al mtodo habla. Por ejemplo, el cdigo
cato micato = new Gat.o ( ) ; miGato. asignaNombre ( "Puff Puf f " ),.
System. out. . println (miGato. obtenNombre System. out.print,ln (miGato. habla ( ) ) ;
resulta en
( ) + ,' dice : ,,
);
clasE Perro exterrd Mascota { publie String trae ( ) { return ,'S, amo. Traer."; )
)
:r:-":?]t*9
Y'.'a!+r]]T:,i]:fi Tryfr
ffi
ryqfi r:]]=..*
*ffi
716
Captulo
l3
Herencia y polimorfismo
Adems de utilizar todos los mtodos heredados, es posible llamar al mtodo trae si trata de un peno:
se
Perro miperro = new perro ( ) miPerro. asignaNombre ( r, Fif i,r ),. System. out . println (miperro . obt.enNombre ( ) + ,, dice
,.
p
COMPROBA
'
rPid
,.
,/
Funciona? La respuesta es s. cuando una variable (como mascotauno) se declara como de clase s (como Mascota),.la variable puede hacei referencia a una instancia de s o a cualquiera de sus subcrases (como eerro y Gato). La inversa no es vlicla; por ejempio,
El de que la misma variable pueda hacer referencia .hecho a una instancia de una clase diferente da por resultado polimorfismo. Las dos ,lgui"nt", s"ntencias producen el mismo resultado, dependiendo de si p es perro o Gato:
Mascota p,
));
));
El m^todo habla se denomina mtodo polimrfico. Si una variable se declara.de tipo i y s" r"fi"r" a una instancia de una subclase de s, entonces es necesario convertir ta varialle a ra subclase."u;;;; ilamen mtodos,no hereditarios de la subclase. Por ejempto, *too trae se define slo en la clase perro. As, cdigos "i
como
Mascota p,
clases nc relacion
(p
trae
<--
NOVLIDO
X3.2
herencia
Zn7
lvlascota p;
);
Siempre que se requiera ilamar a un mtodo nico de una subclase, es necesario convertir ia variable a la subclase si el tipo declarado de la variable es la superclase. Para utilizar en nuestros programas de manera eficaz herencia y polimorfismo, es necesario dominar muchas reglas asociadas con stos. Tales reglas se presentarn en el resto del captulo.
GOMPROBACN
rpida v
ra como
ieSoa
,mplo,
3.
System.out.println(p.trae (
(.) ;
))
Suponga que queremos mantener una clase lista para una clase cuya lista de estudiantes incluye tanto estudiantes no graduados como graduados. Para cada estudiante se registra su nombre, las calificaciones en tres exmenes y la calificacin final en el curso. LJcalificacin final en el curso, aprobado o no aprobado, se determina mediante la siguiente
frmula:
Esquerna de puntuacin
No graduado
de 5,
)s
no
Graduado '
3rro, Qu tipos de objetos deberan utilizase para modelar los estudiantes no graduados
clases no relacinadas
relacionadas si no estn vinculadas por alguna relacin de herencia; es decir, si ninguna de ellas es una clase ancestro o descendiente de otra y tampoco comparten ningn un""r-
y los estudiantes graduados? Bsicamente, hay dos formas para disear estas clases. La primera consiste en definir dos clases no relacionadas: una para los estudiantes no graduados y otra pata los estudiantes graduados. Estas dos clases se denominan clasel no
Captulo
13
Herencia y polimorfismo
!'"
diantes no gradudos. La
graduados como l-u, r"gunda y tercera son Ia ctase EstudianteGra_ duado, para registrar el comportamiento "tur"respcfico de los estudlantes. clase EstudianteNoGraduaao, para r.girtr*it.ornponu-i;;;;;;""urco _graduados, y l de los estudiantes no'graduados.
En realidad, definiremos tres clases. La primera es la clase Estudante, donde se in_ corporarn los datos v comportamiento comunes tanto de los estudiantes
ff [:,:#H::T#ffH-'":"*::i:i::"q]$::'."""'1,i:#i";'"'nandup,icando graduaaos'ililffiiaf|:* ti Jdl;; ;;;; ;;' J" mo do e :,T:::',: :;:#ff n il::l"J #1"nl": ".n
cdigos comunes a ambas clases. Aunque tol estuiantes
qu es r a s do s
tro comn.rLa segunda forma conslste en modeiar los estudiantes no gad.uados estudiantes graduados usando clases que y lq* estn relacionadas mediante una Jerarqua de herencia. Definir dos clases no relacionadls para entidades que comparten.datos o compofta_
publ
non
)
n"ottl.
de ros
esru_
a conrinuacin:
@
l
,'
I I
!.;
/*
class Estudiante { protected final static int NttM DE_EXAMENES =3 protected String nombre; Los campos protegidos son protected int [] examen,. visibles a los objetos protected String calificacioncurso descendientes. i public Estudiante( ) { ths("Sin nofirrrI.
ti
extiende
Java' la clase object se convierte de forma automtica en ra supercrase de una clase si sta se define sin la palabra reservada extends' D" ,e.ni"u -un.tu debe decirse que dos clases no estn i.""iru, relacionadas si no comparten ningrin ancestro comn
rEn
aparte de Object.
.*$,*3.
i
I
13.2
Definicin de clases con
herencia 719
rl sob
s
numExamen)
se in!e dos
los
estu-
acin:
W
Observe que el modificador para las variables de instancia es protected, lo cual las hace visibles y accesibles a las instancias de la clase y las clases descendientes. Si declaramos un miembro de datos de una clase private, entonces este miembro de datos slo es accesible a las instancias de la clase, Si un miembro de datos lo declaramos como public, entonces el miembro de datos es accesible para todo el mundo. Se declaran como protected para que sean accesibles slo a las instancias de la clase y a las clases descendientes. M adelante en este captulo analizaremos con ms detalle el modifica-
dor protected.
extiende
Definiremos las clases EstudianteNoGraduado y EstudianteGraduado como subclaLa diferencia entre estas dos clases reside en cmo se calculan las calificaciones finales del curso. A continuacin se presenta la definicin de ambas subclases:
ses de la clase Estudiante. En Java se dice que una.clase exende su superclase.
int toEal = 0; for (lnt i = 0; i < NUM DE-EXAMENES; i++) i total += examen[il;
)
if
(Lora1/NLM_DE_EXAMENES >=
80) t
,'
"Aprobadorr
rrNo Aprobado'r;
*qry!*
rsdua9rlLurso
int, total = 0; for (int 1 i = 0,' i < NUM_DE_EXAMENES; i++) total + examen Ii] ] if (total/NuM_DE_E)LAIvTENES >= 76 { calif icacioncurso =,[p9[6!srr,. else ] { calif icacioncurso = ,,No Aprobad.o'
,.
(, t
]
En la figura 13'1 s.e muesffa ei diagrama de clases que relaciona estas tres clases. observe el uso del smbolo (#) para er modificador protected. tamuin observe :; las subclases no se muestran los miembros de datos ni los mtodcs heredados. cuando se observa una flecha de herencia que conecta una subcrase con su supercrase, se sabe que los miembros de datos y ros mtodos en ra supercrase tambin son'apricabi; ;#: clases' Se asignan mtodos y miembros de datos a las subclases slo si se definen en las subclases o se redefin91 e1 las subciases (discutiremos la redefinicin en .t^il.^,na, aa,etltg captulo). En ra figura 13.1, ambas subclases tienen asociado ei mtodo :.l."rt: calculacalificacioncurso porque ste est definido en las subclases.
+ NUM_DE_EXAMENES
F nombre
,,-
+Estudiante():void
+ Estr,rdiante(String) : void + obtenCaficacionCurso( ) : String + obtenNombre( ) : String + obtenCalificacionExamen(int) : int + asignaNombre(String) : void + asignaCalificacionExamen(inr, int) : void
+ obtenCalificacionCurso(
) : String
+ obtenCalificacionCurso( ) : String
Figura
13.3
?41
I. COMPROBAC!N
'7 rGptaa /
class X extends y {.
7
.}
Qu modificador de visibilidad permite que 1os miembros de datos de una super_ clase sean accesibles a las instancias de ias subclases?
EstudianteGraduado listaGraduados[20j;
EstudianteNoGraduado listaNoGraduados [20]
;
aile ms
mtodo
Fn el captulo 10 mencionamos que un arreglo debe contener elemenros del mismo tipo de datos. Por ejemplo, no es posible almacenar enteros y nmeros reales en el miso
vlida cuando los elementos del aneglo son objetos. Basta declarar un nico anglo; por ejemplo,
los estudiantes graduados y oro para los no graduados. Esta regla, sin embargo,
arreglo. Para acatar esta regla, parece necesario deciarar dos arregios d.iferentes: uno para
nt es
Estudiante Iista[40];
Los elementos del arreglo lista pueden ser instancias de ia clase Estudiante o de sus descendientes las clases EstudianteGraduado y EstudianteNoGraduado. En la figura i3.2 se ilustra el arreglo con ambos tipos de estudiantes como elementos del arreglol
lista
Figura 13"2
El arreglo lista con elementos que se refieren a instancias de las clases Est.diarteGraduado o EstudianteNoGraduado.
722 Captulo't3
Herencia y polimorfismo
Antes de mostrar cmo se Lltiliza este areglo en er programa, expric.aremos el con_ cepto de polimorfismo. En su forma ms simple, el polimoifisn o ,..uprr., a,una nica variable que se refiere a objetos de diferentes .toi.r.'co"'"i., p"r eJemplo, la declara_
Est.udiante estudiante,.
Con esta declaracin, no sio se puede decir:
estudiante =
nertr EstudianteNoGrad.uado(
);
En otras palabras, la variable_ simple estudiante no est limitada a objetos de la clase Estudiante, sino que puede referirse cualquier objeto e las clases que descienden de Estudiante. De manera semejante, es posibl hacer lgo to ,igui"nt",
"o*o
lases
una variable de la clase X se refiera a un objeto hermanas de la superclas o de clases hermanas de X. Las clases hermanasson aquellas que comparten un ancestro comn' Por ejempio, las siguientes sentencias no son vlidas:
,.
ruOVt_lOO_____-
I est.2
,.
Luego, para calcular la calificacin del curso utilizando el arreglo lista se ejecuta:
si lista[i] se refiere a un EstudianteGraduado, entonces se ejecuta el mtodo calculacalificacioncurso de la clase EstudianteGraduado, y si se refiere a un EstudianteNoGraduado' se ejecuta el mtodo calculacalificacioncurso de la clase EstudianteNoGraduado.
,,"fiere a mtodos
El
de
'13"3
v?"3
Ciierentes ciases, ciependrendo de si el objeto al qlle hace refencia listalil. El polimorfismo permite mantener 1a lista de clase con un aregio en vez de mantener un arreglo por sepaiado para cada tipo de estudiante, con 1o cual el procesaniento se simplifica enormemente.
.beneficios del
,:lrolimorfismo
Ei pomorfismo hace posible extender y modificar un programa de manera continua y fci1. Suponga, por ejemplo, qrie es necesario aadir un tercer tipo de estudiante; a saber, un estudiante invitado, al programa de la lista de clase. Si se tiene que definir un arreglo diferente para cada tipo de estudiante, esta extensin obiiga a definir una nueva ciase y un tercer an"eglo para estudiantes invitados. Pero con polimorfismo, slo es necesario definir una nueva subclase de Estudiante. Y en la medida en que esta nueva subclase incluye el mtodo calculaCalificacionCurso correcto, el ciclo for para calcular Ia calificacin del curso de los estudi.antes sigue siendo el mismo. Sin polimorfismo, no slo necesitamos aadir el nuevo cdigo, sino que tambin debemos reescribir el cdigo existente para dar cabida a los cambios. Con polimorfismo, por otra parte, no necesitamos modificar el cdigo existente. La modificacin del cdigo existente es tediosa y muy propensa a errores. Un ligero cambio en un cdigo existente podra ocasionar que el programa dejase de funcionar cofrectamente. Para tener la cetteza de que un cambio en una porcin de un cdigo existente no afecta otras porciones del cdigo existente en forma adversa, es necesario comprender muy bien el cdigo existente. Adems, la comprensin del cdigo, especialmente si es largo y/o realizado por otras personas, es una tarea que consume mucho tiempo. Un elemento del aneglo lista es una referencia a una instancia de la clase EstudianteGraduado o de la clase EstudianteNoGraduado. La mayor parte de las veces, no necesitamos saber de qu tipo es. Sin embargo, hay veces en que necesitamos conocer la clase del objeto al que se hace referencia. Por ejemplo, podemos querer buscar el nmero de estudiantes no graduados que han aprobado el curso. Para determinar la clase de un objeto, usamos el operador instanceof. Este operador se utiliza como se muestra a continuacin:
; de
la ciase lcienden de
eJecuta;
int contadorNoGraduados = 0; for (int i" = O; i < numeroDeEstudiantes; i++) t if ( lista Ii] instanceof Estudiant.elloCrad.uado ) {
a
lculaCa li-
conLadorNoGraduados++,.
JoGradua-
\
J
duado. El
Ltodos de
724
Captu[o
13
Herencia y polimorfismo
"rdpida /
rl
Camion Vehiculo
c = new Vehiculo( ); - ); v = new Camion( Mot.obicleta m1 = new Vehi-culo ( ) ; Mot-ocicleta 12 = new Camion( );
2.
En esta seccin y en las secciones 13.5 y 13.6 describiremos las reglas de herencia. En esta seccin explicaremos qu miembros (variables y mtodos) de una superclase se heredan en una subclase y cmo se accede a estos miembros. Adems de declarar miembros public y private, podemos declararlos como protected. El modificador protected es til slo si se usa con herencia. Considere las siguientes declaraciones:
suDer es una class super t 'G reservada: no la use. int campo_public_Super; ,public proLected nt campo_protected_Super; private int campo_private_Super; public Super0 { campo_public_Super = l-0; campo_prot.ected_Super = 20 campo_private_Super = 30; palabra
)
I
class Sub exlends Super { public int campo3ublic_Sub; protected int. campojrotected_Sub; private int campo_private_Sub; public Sub O { campo_pub1ic._Sub = 100, campo_protecLed_Sub = 200; . campo3rivate_Sub = 300 i
)
)
Para ilustrarlo usamos variables de instancia, aunque las reglas que se describen aqu son igualmente vlidas para otros tipos de miembros (variables de clase, mtodos de clase y mtodos de instancia). Para los tres modificadores usamos la representacin grfica que se muestra en la figura 13.3.
XN,
'
3.4
Herencia y accesibilidad de
miembros VZs
:Sub
EstO muestra
encia. En
tse Se he_
riembros rd es til
Jerarqua tle clase
r-:r..]
ffil
Fig*ona
Instancias
?3'3
Representacin grfica de superclases y subclases con miembros pub!i<, private y prote(ted. (Nofd: ilustracin y no es un diagrama UwIL formal.)
Usted ya conoce la diferencia entre los modificadores public y private. {"In miembro pblico (public) es accesible para cualquier mtodo, pero un miemtro privado (private) slo es accesible a los mtodos que pertenecen a li misma clase. A continuicin se
ilustrar esta cuestin. Considere una clase que no est relacionada con las clases super
y Sub:
class Cliente { public void prueba O { Super miSuper = new Super O ; Sub miSub = new Sub O ; int j. = miSuper. campo_public_Super,. int j = miSub.campo_public_Super; ,//hered.ado por vuoo _-> int, k = miSub.campo_public_Super;
)
miSub
son que
Los miembros pblicos de una clase, sean heredados o no, son accesibies desde cualquier objeto o clase. Los miembros privados de una clase, por otra parte, nunca son accesibles desde fuera del objeto o clase. En consecuencia, todlas las siguientes sentencias, si se sitan en el mtodo prueba de la clase criente, no son vlidas:
Ney
vovlloo----->
lf
V26
Captulo
..*
l3
Herencia y polimorfismo
{l ienie"
:Cliente
:Sub :SuDer
?r- -_-l/
Slo los miembros embros pblicos, los definidos os para la clase y los heredados, ados, son sc visibles desde fr-reia.Todo a.Todo Ilo dems est oultor desde fuera.
1
\, \
\t--.
,.: J
-]./
: l-lx:],'.
Slo los miembros pblicos son visibles
X:l:'
Un miembro protegido (protected) es accesible slo a los mtodos que pertenecen a la misma clase o a las clases descendientes. Es inaccesible a los mtodoJde una clase no relacionada. Todas las siguientes sentencias, si se colocan en el mtodo prueba de la clase Cliente, no son vlidas:
X ruovl-loo->
Sub; Super,.
En la figura 13.4 se resume la accesibilidad de los miembros de una clase desde un mtodo de una clase no relacionada. A continuacin estudiaremos la accesibilidad de los miembros de una clase desde los mtodos de un objeto Sub. Un mtodo en el objeto Sub puede acceder tanto a los miembros protegidos como a los miembros pblicos de Super, pero no a los miembros privados de Super. En la figura 13.5 se resume la accesibilidad de los miembros de un mtodo de un objeto Sub. La figura 13.5 muestra el caso en el que un mtodo de un objeto Sub est accediendo a sus propios miembros. Todo, salvo los miembros privados de ia clase Super, es accesible desde un mtodo de la clase Sub. Qu ocurre cuando se accede a ios miembros de un objeto desde otro objeto que pertenece a la misma ciase? Si un miembro X, ya sea heredado o definido onu Llur., accesible desde una instancia de la clase, entonces X tambin es accesible "n "t desde todas 1as instancias de la misma clase. La figura 13.6 ilustra que una instancia puede acceder a los mtodos de otras instancias de la misma clase.
'3.4
Aercsihiiidai iescie un
niri. tie
Herencia y accesibilidatJ de
miembros
VAV
:Sub
ia lir:lc'5ub"
LI
i-i I it
todo
Desde un mtodo de Sub es visible, excePto los miembros Privados de su superclase.
il
.:1
I L-=-
Figura 13.5
y protected' Todo, excepto los miembros de tiPo Diferencia entre los modificadores public, Brivate la clase Sub' private de la clase Super, es visible desde un mtodo de
visibles
Si un miembro de dtos es
accesible desde unalnstancia, ese miembro de datos tambin es accesible desde otralnstancia
protegido o Pblico.
necen a
lase no
adela
FiEuera '13.6
ffice5blesdesdeunainstanciatambinsonaccesiblesde5deotrasinstanciasde
la misma clase.
class SuPer
;de los
-.>
niemivados
i
)
do
de
iendo
scesi-
Super
l
as
que las
subASub
( Sub
otsrosub) {
se, es a los
Captulo
13
Herencia y polimorfismo
rap
]
Todas las sentencias en los dos mtodos, excepto la ltima en subASub, son vlidas porque los miembros accesibles a un objeto tambin son accesibles desde otros objetos de la misma clase. Ahora, considere las dos clases siguientes:
class SuPer { public void. suPerASub (Sub sub) { int i = sub.campo-public-Sub,' / VEI-IOO sub . campo_protected_Sub I nt
vsub . campo_privat.e_Sub
;
X ruovLtoo- I io,
] ] class
)
Los dos mtodos muestran que slo los rniembros pblicos de un objeto son accesibles desde otro objeto si los dos objetos perteneeen a diferetes clases. Si una clase es una subclase de la otra carece de importancia aqu.
autom
Adems de los modificadores publc, prvate y protected, Java soporta un cuarto mdificador de visibilidad denominado visibifidad del paquete. Si en la declaracin no se incluye ningn modificador explcito (publi<, private y protected) etonces el componente ei visible para el paquete, lo cual significa que el componente es visibie desde cuajquer mtodo de una clase que pertenezca al mismo paquete:que,l clase del componente.'La visibilidad det paQuete no es tan lgrtic com la de,loS tios tres modificadores de visibilidad y, por ello, no se ana,
liza en eltexto,
13.5
Herencia y
constructores ZZg
f t.
,''oMPRoBAchi
lu.tu."
super, es X
u...ribl" desde
una subclase
raotaa -./
a L.
Si X es un miembro protegido de la clase Super, es X de una instancia accesible desde otra instancia de Super? eu ocurre con ls instancias de una subclase de 5uper?
vlidas,.
objetos
A diferencia de otros
]
es equivalente a
suPer ( )
; <.-
constructor de la superclase.
ar-
,,)
fil.
ld)
'nts-..
tn
a-
super( );
llama al co'nstructor de la superclase. Cada clase tiene una superclase. Si la declaracin de la clase no designa de forma explcita la superclase con la lusula extends, entonces la superclase de la clase es ia clasJobject.
730
Captulo
13
Herencia y polimorismo
Si declara'un constructor, entonces no se aade ningn constructor 1 -""'c ..^_ --^ forma Predeterminada a la clase. Por ejemplo, si define una clase
"orno,
i
\ t
entonces una sentencia como
su_
super ( )
,.
como la primera sentencia del constructor. Por ejemplo, si el constructor se define como
i;
:
:-,::=:
class Vehiculo { private String niv; public VehcuLo (String numeroldVehiculo) { niv = numerofdvehiculo;
)
contrario
aadi pro'
debido
ac
con el
t*,,,1#j.
13.5
Herencia y constructores
73'
)
Puesto que la clase tiene un constructor, a aquella no se aade ningn constructor predeterminado. Esto significa que una sentencia como:
nterior
::
.,i:
rdela
su
::
-
instancia de Vehiculo sin un nmero de identificacin del vehulo. A continuacin consideraremos una definicin de subclase para camiones. Un objeto Camion tiene una variable de instancia adicional denominada cargaMaxima que se refiere al peso de la carga mxima que puede transportar el camin. Se supone que la carga mxima puede varir (por ejemplo, dependiendo de cunto paga de tarifa e1 dueo del carrn). A ontinuacin se presenta el primer intento:
class
Camon extends
Vehiculo {
nuevaCarga) {
Si compilamos esta definicin, obtenemos un effor del compilador. Debido a que para la ciase no se ha definido ningn constructor, el compilador aade un constructoien forma predeterminada.
Este cOnstructor llama al cons*uctor de la supercLase sin argumentos, pero no existe ninguna coincidencia con el constructor en la sperclase. As, iesulta un error de compilacin. A continuacin se presenta una definicin correcta:
,
llamada; en caso
class Camion extends Vehiculo { private int cargaMaxima,. public Camion(nt pesoMaximo, String niv) { ::_-.-._-> super(niv); cargaMaxim = pesoMaximo; public void establecerCargaMaxima(int nuevaCarga) {
)
Vehiculo.
#.*r
t5
Captulo
'[
Herencia y polimorfismo
cargaMaxima = nuevaCarga;
O{
EstudianteNoA continuacin, este conocimiento se aplicar al diseo de las clases el nombre, enque acepte constructor un queremos Si Graduado y EstudianteGraduado.
ya que el constructor definido tonces es nlcesario definir un constmctor en ambas clases, que podemos cfear instancias observe clases. estas lo heredan no en la clase Estudiante continuacin: a muestra se de estas clases como
::::
lr.'j ill,
1
estudiantelestudiante2
y no porque el defidebido a que el constructor predeterminado lo aade el compilador, constructores de que los nido en la clase Estudiante io hereden las subclases. Recuerde una superclase no 1os heredan sus subclases' recordarse para el A continuacin se presentan una regla y una directriz que deben
constructor de una subclase:
i'i;;i
j-ii'.
ll:,,
rti,i
clase abstr
)l
Siempreproporcioneunconstructorparucodaclasequedefina.Nodependade
io
La
abst
una
i':i,,''if*:l!1R
1. Cmo se llama al constructor de la superclase desde su subclase? 2. Qu sentencia debe aadirse al constructor de una subclase si el programador
incluye en forma exPlcita uno?
no
Li
=
=
=
new EstudianEeNoGraduado
;
;
I
1
3,6
733
d,"_"
)inbre, en_
rr
definido
insrancias
Cuando definimos una superclase, a menudo necesitamos crear instancias de 1a rnisma. En la seccin 13.5 definimos 1a superclase Estudiante y sus dos subclases, EstudianteGraduado y EstudianteNoGraduado. Se proporcionaron ejemplos de creacin de instancias de ambas clases, pero no se crearon instancias de Estudiante. Tiene sentido crear una instancia de 1a clase Estudiante? Dependiendo de si necesitamos o no crear instancias de Estudiante, debemos definir la clase de manera diferente. En esta seccin describiremos formas distintas para def,nir una superclase. Aun cuando podamos_crear una instancia de Estudiante si as 1o deseamos (debido a la forma en que se ha definido actualmente la clase), existe la necesidad de crear una instancia de Estudiante? Si un estudiante slo puede ser graduado o no graduado, entonces no es necesario crear una instancia de Estudiante. De hecho, debido a la forma en que se ha definido la clase, si se hubiera creado una instancia de Estudiante y se hubiera almacenado en el arreglo lista, el programa habra fallado. Por qu? Porque la clase Estudiante carece de un mtodo calculaCalificacionCurso' A continuacin consideraremos dos casos. En el primero, se supone que un egtudiante debe ser un estudiante graduado o un estudiante no graduado. En el segundo caso, se supone que un estudiante no tiene que ser un estudiante graduado o un estudiante no grduaOo (por ejemplo, el estudiante puede ser un estudiante invitado no matriculado).
easo
,E:
Ef,
En el caso en que un estudiante deba ser un estudiante graduado o uno no graduado, slo
clase abstrcta
-.
necesitamos instancias de EstudianteGraduado y EstudianteNoGraduado. Por tanto, necesitamos definir la clase Estudiante de forma que no'sea posible crear instancias de ella. Una forma consiste en definir Estudiante como una clase abstracta.Una clase abstracta es una clase definida con el modificador abstracto, y de una clase abstracta no es posible crear instancias. A continuacin veremos la manera de definir la clase abstracta Estudiante.
La palabra clave
NUM-DE-EXAIvIENES =
:::-
ri :\:
protected String nombre protected int Il examen; protected String cal j-f icacionCurso public Estudiante O
t
lor no
this(ItSin nombre"),'
i
de Ia
con-
1:t:9.:1"ttbu
tnt[to*ttt-'"
::l::"t"'
734
Captuto
l3
Herencia y polimorfismo
public String cal_culaCalificacionCurso O { return calificacionCurso. public String obtenNombre O { return nombre,.
)
---'
])
,.
nombreNuevo) {
numeroExamen,
,)
)
mtodo abstracto
examen [numeroExamen-1]
= califica"r:::":::lficacioncurso)
implementacin
de un mtodo
un mtodo abstracto esn mtodo con la palabra crave abstracto, y termina con punto coma, en vez de con un cuerpo de mtodo. unu ;, ,b;;;;;;;si Ia crase conriene ur mtodo abstracto o noptopo..ionu unui.llemenracin se dice que un mtodo esiimpremriri"^riti."n",1., " *.1o abstracto heredal " .ii,o". no tiene mtodos absrractos y-no posee "u.rpo rr*"^0", si una suclas, mJtodos uurtru"i, sin implementa (y no puede incluir la palabra su definicion e cl.sel entonces la subcla se ya no es abstracta, por.lo que y" p"ri1" crear sus instancias. una clase absracta "e tn"ruitliffiru.tuu" "r uortr..t su definicin. observr que la clase abstracta Estudiante tr.n. ,lnu "nri.iJ".-.'"f,ia"euio "n a que ra crase incluye el mtodo abstracto calculacalificacioncurso que no tiene un cuerpo de El objetivo es permitir a sus subclase. mtodo. lu" fioporcionen ra imprementacin der mtodo calculaCalificacionCurso. Si una subclas no r
.i*
cla"JJ;;;n
superclase abstracta
..-
i;::rt;;:i:"cu.ando
La clase
s r a s ubcr as e 1p' c1a' " no es posibre crear instancias de la subclase. "jT se ffata de una,;;;;"", a
;."i i::
.Cn3ejos,,
pistasy,' obstcloi
no crear nstancias de ra ctase. sn ", emb;r;;, una nsrancia no necesariamente implica que la clase sea abstracta. El objetivo de una clase abstracta es defnir aspectos comunes de todas ,u, iuo.tur"s y dejar que argunas porciones, es decir' mtodos abstractos, se.an comptetauos por las suLctases iniuu"ler. La clase Math se clasfica como una crase no i^ri*.iuor., ,n. .rur" fjr.l.".r.r no es posibre crear ninguna instancia. observe que por efncion ,nu .iu!" .ur*.,u es una clase no nstanciabre, aunque Ja inversa no es cierta. Hay ctaies no instanciabres, por ejemplo, la clase Math, que no son uolru.aur. si queremos Jrni, una clase no ;; ; I l, n u,.s,," ; itr l,?l f;
Math, es una crase abstracta? Es cierto que no es posibre crear instancias de Math' pero no es una .r;;;;;;;i. r, ,n, .rur" urriicra, entonces se pueden
ta ctase
";;;;";
!,"*r"
"',?
i*"":',,,.i
";;
"
;,;, ;
3,6
abstractos
1a
735
En un diagrama de objetos, una clase abstracta se representa utilizando clave abstract. La superclase abstracla Estudiante se lepresenta como
Estudiante
{
palabla
abstracta }
rso) i
caso 2: El estudlante no tie'e por qu 5er graduado o E'o graduado Para el segundo caso, en el que el estudiante no tiene por qu ser graduado o no graduado, podemos disear las clases de dos formas. El primer enfoque consiste en hacer instanciable la clase Estudiante. El segundo enfoque consiste en dejar la clase abstracta
punio y tiene un
:redado. ubclase )mentar
Estudiante y aadir una tercera subclase; por ejemplo, OtroEstudiante, pafa tratar con los estudiantes que no son graduados ni no graduados. Los estudiantes que no son graduados ni no graduados los denominaremos estudiantes no matrculados. Supondremos que estos estudiantes aprobarn el curso si su puntaje medio en el examen es mayor que o igual a 50. Con el primer enfoque, la clase Estudiante se define como se muestra a continua-
cin:
Ya no es una clase
------>
abstracta
class Estudiante { protected fna1 static int NUIVI_DE_EXAMENES = nombre; protected String examen; protected j-nt il calificacionCurso; protected String public Estudiante( ) { this(rtSin nombre");
)
de
alo
icacioncurso
to
ta
3S Ya no es un
)
mtodo abstracto
;e
le
e
5,
public void calculaCalificacionCurso( ) { int t.otal- = 0; for (int = O, i < NUM_DE-EXAMENES; i++) total += examen[1];
)
if
736
Captuo f
Herencia y polimorfismo
calificacioncurso =
'No Aprobado";
] public String obtenCalificacionCurso( ) { return calif icaconcurso ; ] public String obtenNombre O i rturn nombre;
i
public int obtenCalificacionExamen(int return examen lnumeroExamen- 1] ;
)
numeroExamen)
public void estableceNombre (string nuevoNombre) nombre = nuevoNoilre; ] public void e s t ab1 ec eCal i f icac ionExam':jli:
examen lnumeroExamen-]-l
r:::illllllll;
= cal-ificacionExamen''
)
Estudiante pala lepresentar La clase ya no es abstracta, y podemos clear una instancia de a los estudiantes no matriculados con el segundo enfoque, la clase Estudiante 1a dejamos como abstracta. Para reprea los eitudiantes no matriculados, definimos una tercera subclase denominada
ffi ffi
class OtroEstudiante extends Estudiante { public void calculaCalificacionCurso O { int total = 0; for (in! i = 0; i < NUM-DE-EXAMENES,' i++) { toLal += examen[i];
)
if
(tota1/NLtvl-DE-EXAMENsg
= 50) {
COMPS
La figura 13.7 es un diagrama del programa que incluy-e la tercera-subclase. Todo depende de cadasituaiCul enfoque es m;jor? No existe una rspuesta fcil. situacin dada, podemos para una mejof es el enfoque cul cin]A fin de determinar Considere, por y extensiones. las rnodificaciones lai facilita pieguntarnos qu enfoque
n3"6
Estudiante
{
abstracr.cs 7=7
abstract
OtroEstudidnt
'tej
ren). {
esentar
repreninada
.
ejemplo, qu enfoque facilita 1a modificacin si se tiene que aadir un nuevo tipo de estudiante, por ejemplo, estudiantes becarios. O bien, consiere el caso en que se modifica 1a regla de asignacin de calificaciones a los estudiantes no graduados y u lo, estudiantes graduados; por ejemplo, una regla donde los criterios de aprobacin son los mismos. Finalmente, no todos los mtodos se pueden declarar omo abstractos.
Los
. Mtodos . Mtodos
privados
,.,
,:
wiffi**x,rytr,$&kffiK**!:51#j!i!its*$i,
COMPROBACN
l,$ ,
txr.ini;iri::i*
rapma
/rt
,/
ua10s
)or
]
class CuentaAhorro extends Cuenta {
i
Deoimos "Directorioverl es un Directorio,, ..cuentaAhorro y es una cuenta,,. Debido esta semejanza' los a Programadores principiantes tienen oificultades en distinguirlas cla_ ramente. Aunque se parece-n, sus prpsits son bastante comportamiento comn (definido por mtodos abstractos) sus e clases no ,"1;.i"";;;;. y una crase puede implementar mltiples interfaces. pi ."*pr", puede "i*irr. ,* clase nica persona que implemente mrtiples interfaces, .o-Lonorctor, viajero y cicrista. Por orra parte, la heencia.se uru p*u compartir caigo Jo;n (incluyendo tanto miembros de datos como mtodos ent ias instancias de cises relacionadas. por eiemplo' las clases EstudianteGraduado y EstudianteNoGraduado son subclases de la lase Estudiante' las clases Camion y tuotciclei" son subclases de la clase vehiculo, etc. Las superclases incluyen miembroi de datos yro metooos que son compartidos por ras subcra_ ses' La relacin ES-LrN que existe na suclur" y .u ,;p.;;il; es una especializa_ cin' de la misma manera en que camion "nt " es un Vehiculo especializado. Esta relacin especializacin no existe de
con
La intertaz Java se
diferen;.
reutilzacn
cdigo por
composicir
li
interfaz Java.
'-::i:::::'tu:
to."I
13.8
forma especializada de otra entidad B, entonces mod_ Ielas usando herencia. Declare A co.i ruOrtore de B.
iio
. :-i
3.8
Ejemplo de
desarrollo
7Sg
1a
principiantes a menudo cometen este elror. Suponga que quiere definir una clase ciue rnantenga una iista de CD de msica. Cu1 cie las dos siguientes definiciones constituye
un mejor diseo?
herencia. i-os
tanto clase
ejem-
:. Las
rbcla-
zliza-
Ms all del problema conceptual, la definicin de la clase CDManager como una subclase de Arraylist presenta debilidades prcticas. Debido a que es una subclase, el cliente de la clase CDManager puede llamar cualquier mtodo definido en la superclase ArrayList. Pero, tiene sentido que el cliente llame ei mtodo como capacidadSegura? Otra debilidad es la dificultad para cambiar la implementacin de la clase CDManager. Suponga que necesitamos modificar la clase Ce estructura de datos de Arraylist a HashMap para un mejor rendimiento. Con el enfoque de la herencia, cualquier cliente que utilice los mtodos heredados de ArrayList necesita reescribirios. Con el enfoque de composicin, el cliente que use slo los mtodos definidos por la ciase CDManager conti.nuaclase
de
f 3.8
vo de texto indicado por el usuario, calcular las calificaciones del curso y mostrar
:..1'.!
,::::':':r:
t..,,='
,tj
resultados. Supondremos que el archivo de texto se ha creado utilizando un editor de textos u otra aplicacin. Por ejemplo, un profesor puede tener almacenadas las calificaciones de sus estudiantes en un cuaderno. En vez de calcular manualmente las calificaciones con lpizy calculadora, introduce los datos en un archivo de texto y aplica este programa para calcularlas. Otro escenario posible es que el profesor use algn tipo de software que le permita mantener registros de los estudiantes. Suponga que esta aplicacin no permite al profesor utilizar dife-
fi}
Captulo
'!
Herencia y polimorfismo
tl
no graduados y de los esturentes frmulas para calcular las calificaciones de los estudiantes a un archivo de texto y diantes graduados. En este caso el profesor puede exportar datos no graduados y de los estudiantes los de calificaciones las para calcular utilizar el programa archivos de texto para transfeestudiantes graduados usando las diferentes frmulas. El uso de de software' rir datos de una aplicacin a otra es una prctica comn en aplicaciones adoptaremos las polimorfismo, y el la herencia de empleo el en Para centrar la atencin forma diferenen implementarlas ejercicio como deja se y salida. de rutinas bsicas de entrada 5 se pide y ejercicio en el objeto archvo un en datos los guardar 4 se solicita te. En el ejercicio
usar la clase Scanner para entrada.
-d
'
Escribir una
ndca
del
curso
archivo de texto organizado de la forma en que se Las calificaciones continuacin y muestre las calificaciones finales del curso. y para los esgraduados para estudiantes los diferente se calculan ie forma
aplicacin
que lea un
tudiantesnogratduados,segnlasfrmulaspresentadasenlapginaTlT.Elformato
del archivo de texto es el siguiente:
n .
Se
c
En la
Plan global
lmplementaremos una clase que
pfoglarna
1.
,,,2, Calcule
3. lmprima
los resultados.
<Examen
g7 90
<Tipo> <Nombre>
N
G G
1>
<Examen
78 95 77
85
2>
<Examen 3>
90
,Iohn Doe
Jil1
,Jones
87
68 80
N N
67
80
69
79
FlN
FiEura 13.8
los exmenes. G al inicio de la lnea Un archivo de texto que contiene los nombres y las calificaciones de graduado' representa a un estudiante graduado y N, a uno no
'0
3.8
Ejemplo de
desarrollo
74'g
:E
iOS eStU_
Para leer un archivo de texto, usaremos los objetos estndar de E/5 Fle, FlBeReader y BfferedReader. Para calcular las calificaciones del curso, usaremos las clases Esttdias'te, EstudianteNeGraduado y EstudianteGraduads definidas antes en el captulo. Las frmulas para calcular las calificaciones del curso se definen en sus mtodos calc.flaCaliflcacsr'Curso respectivos. Debido a que el archivo de entrada es un archivo de texto, para cada lnea
del archivo debe crearse un objeto EstrdianteGraduado o un objeto Estud!anteNoGraduado, de modo que sea posible llamar a su mtodo ealculaCalificacionCurso. Para almacenar los objetos estudiante creados (instancias de Estcdiaa"teGnadciado o de EstudianteNoGraduado), usaremos un arreglo de objetos Estudia'te para adquirir ms prctica
en el uso de arreglos.
ses auxiliares. La
Para centrar la atencin en los tpicos de herencia y polimorfismo, utilizaremos dos claprimera es la clase OutputBox que se usa para mostrar las calificaciones del
'e se
,ne5
;
e5-
curso y guardar los resultados en un archivo de texto. Sus mtodos print y prirntln se utilizan para la salida y su mtodo saveToFile se usa para guardar los datos en un archivo de texto. El mtodo saveToFile guarda en un archivo designado el texto completo que se encuentra en un OutputBox. Si el archivo ya existe, entonces el contenido original del archivo se sustituye por el texto que se muestra actualmente en el OutputBox. A menudo necesitamos la capacidad de guardar el texto en un formato diferente. Por ejemplo, suponiendo que la informacin del estudiante incluye su nmero de identificacin, el profesor puede estar Interesado slo en guardar los cuatro ltmos dgitos del nmero de identificacin y las calificaciones del curso de modo que los resultados se puedan poner en un tabln. Si queremos guardar el texto en un formato diferente, es necesario implementar un mtodo idneo que cuente con
esa capacidad.
La segunda clase auxiliar es la clase MalrWindow. Nuestra clase principal se denominar CalculaCalificacion, y como otro ejemplo de herencia, hacemos que sta sea una subclase de MairWindow. De suyo, MainWindow es una subclase de JFrare, y posee la funcionalidad
ato
rombre>
?xamen.
tsculas
de colocarse en el centro de la pantalla (entre otras caractersticas). Los detalles de subclasificar la clase JFrarne se abordan en el captulo 14. A continuacin se muestra el documento de diseo de trabajo:
clases del
Documerto de diseo:
CalculaCalif icacion
Propsito
El objeto de control de alto nivel gestlona otros objetos del programa. La clase es un;ubclase de ia
programa
Clase
CalculaCalificacion
'
clase asistente
Mai-nwindow.
principal instanciable.
OutpuLBox
'..:
Un outputBox se usa para mostrar los datos de entrada y las calificaciones calculadas del curso. stos son objetos de lgica de aplicacin para estudiantes. La clase Estudiante es una superclase abstracta. Estos objetos son ncesarios para leer datos desde un archivo de texto.
EstudianLeGraduado
'
'
lnea
-'.::
,:
'
:=ii :::=.=l
, ;i. :: lt.
- ; I 1ir: ::.::,:
. .
.r=g-
:=-
742
Captulo
'!
Herencia y polimorfismo
13"8
Figura 13.9
figura 13.9 es el diagrama del programa. A continuacin abordaremos los mtodos de CalculaCalificacion. Qu tpo de mtodos pblicos debe soportar la clase? Debido a que un objeto CalculaCalificacion es un objeto controlador de alto nivel, necesitamos un nico mtodo pblico para iniciar las operaciones. Definiremos un mtodo denominado procesaDatos que lleva a cabo las tres tareas principales. El mtodo main de CalculaCalifica(on llamar a este mtodo.
La
public static void main(StringlJ args) i calculacali.ficacion calculacalif = new Calculacalificaciono calculaCalif . procesaDatos O ; ]
El
ible ( true)
I *
if
);
]
El mtodo leeDatos devuelve true si los datos de entrada se leen correctamente desde un archivo de texto y el arreglo de objetos Estudiante se crea apropiadamente. A continuacin se presenta el documento de diseo de CalculaCalificacion:
diseo d paso 1
*&*
'13,8
Ejemplo de
desarrollo 743
calculaCalif ica-cion
Propsito
Crea e inicializa tos objetos usados por un objeto
ffltodo <consLructor>
procesaDatos
Visibiidad
publ ac
CalcuIaCal if icacion.
leeDatos
Abre y lee datos del archivo de texto y rea un arreglo de objetos EstudianLe a partr de los datos de entrada. Si la operacin es exitosa, devuelve true. Explora el arreglo de objetos calificaciones del curso.
calcul-auaI].!acac].0n
r-mprame-
EsLudiante
y calcula las
Resultados
:ipales.
El
necesarjo
:ion O ;
4. lmplementar
5"
La
el mtodo leeDatos. Definir cualquier otro mtodo necesario para la implementacin de leeDatos.
Finalizar y buscar mejoras.
1 -,
utBox
implementacin del mtodo ms difcil, leeDatos, lo pospondremos hasta el final. Algunos programadores prefieren tratar los aspectos ms difciles del programa al principio, y no hay ninguna regla estricta que permita ordenar los pasos de la implementacin. El lector debe ordenar los pasos en la forma en que se sienta ms cmodo. Sin embargo, esto no significa que usted puede implementar los mtodos en forma aleatoria. Siempre debe planificar cuidadosamente lcs r:asos de la implementacin, de modo que sgan una secuencia lgica. Para este programa, empezamos con la rutina de salida, de modo que sea posible utilizar la rutina de salida final para probar otros mtodos, en vez de definir una rutina de salida temporal para efectos de depuracin.
Comenzaremos con los miembros de datos y los constructores para la clase CalculaCalifieacion. Empezamos con los siguientes miembros de datos:
:sde un
lcton 5e
V44
eaptulo
l3
Herencia y polimorfismo
'!
3.8
La creacin de los cuatro prlmeros objetos es drecta, aunque necesitamos pensar un en el arreglo [ista. Cul debe ser el tamao cie este arreglo? Hay varias posibilidacles:
'l
2. 3.
pu:
]
pu.
La opcin 3 no es nada atractiva porque requere un cambio en la especificacin del problema. Adems, requerir que esta informacin est presente en el archivo de entrada hu.* j, n, difcil la tarea al usuario, quien tiene que ocuparse de contar el nmero de lneas que contien; el archivo. Esta tarea tan tediosa debe dejarse a la computadora. As, implementaremos las Qpciones 1 y 2.Si los datos no pueden ajustarse a un arreglo de tamao preasignado, entonces utilizaremos la tcnica que se analiz en el captulo 9 para expandir el arreglo. Declararemos una constante
private
nt
TAIv1ANIO_PREDETERM
= 25;
llPr
p
public
this
)
Cal-cul-aCalif icacion
(TAI4ANIO-PREDETERM)
O
;
cdigo del
paso
1
Observe que no es posible crear archivoEntrada, lectorArchivo y lectortsuf sino hasta que se abre el archivo. Estos objetos los crearemos en uno de los mtodos que definiremos nls tarde. Para el esqueleto del programa incluiremos sentencias de salida temporales en los mtodos privados para comprobar que sean llamados correctamente en el orden idneo. A continuacin se muestra el esqueleto:
Desarrol-lo de ejemplo del captulo 13 : Calcular' las calificaciones de Estudiantes no graduados y Est,udiantes graduados Archivo : Cal-cuf aCalif icacion. j ava
'J:=:
J.o
EJstf
tfxu G ttgiar(lo
,15
//--------PASo 1--------// class Cal-culaCalificacion extend.s MainWindow { private st.atic final inL TAMANIO-PREDETERM = 25; privat,e OutputBox cuadroSalida,. private Estudiante[] lista; public CalculaCal-ificacionO i This (TAMANIO_PREDETERM) ;
)
n del pro_ hace.ms
cluir el ta_
contiene
emos las' 3ntonces
,
publc CalculaCalificacion (int tamanioArreglo) { superO; //Ll-ama explcitament.e al constructor de 1a superclase cuad.roSalida = new OutputBox(this) ; lista
)
/ / --/ / PrlrlcLpaL
//----
public static void main(Stringll args) { Cal-curaCalificacion calculacalif = new Carculacalificaciono calculaCalif . procesaDat.os ( ) ;
)
'i
if
ue 5e
arde.
calculaCali-f icacion ( ) ;
rtoonti-
(exitoso) i
]
O
O{ ,,)
/ /TEMI
eaptulotr3
Herenciaypolimorismo
3.8
/ /TEMP
Ejecutamos la clase principal y el esqueleto de la clase CatculaCalificacon para efectos de verificacin. Una vez que se ejecuta lo anterior, en la pantalla veremos la ventana principal de alto nivel (CalculaCalificacion) y un cuadro de salida, as como los siguientes mensajes en el
OutputBox:
rso,2:
En el desarrollo del segundo paso, aadimos una rutina que ubica el resultado en un cuadro de salida (cuadroSalida). Para implementary probar este mtodo, necesitamos crear el arreglo lista. lncluiremos cdigo temporal dentro del mtodo leeDatos para construir y probar el arreglo lista. Podemos utilizar los siguientes ciclos for:
for I
primera mitad del reglo tiene estudiantes : graduados.
r
(int i = O; i < i5; i++) { listalil = new EstudianteNoGraduado0; listalil.estableceNombre( "No graduado # " + i
]
r--------------- for (int i = 15,. i < TAMANIO PREDETERM; i-++) t lista [i-] = new EstudianteGraduado ( ) ; r segunda mitad del lista [i] . estableceNombre ( "Graduado # " + i reglo tiene estudiantes
I
'aduados.
lista Ii] . estableceCalificacionExamen (1, 80 + i) lista Ii] . estableceCalificacionExamen (2, 85 + i) lista Ii] . estableceCalificacionExamen (3, 90 + i)
)
para crear una lista temporal para efectos de depuracin.
ry_
+4!ts=
3,8
Ejemplo de
desarrollo 747
A continuacin disearemos el mtodo mpninreResultados. Cuando se llama a este mtodo, tenemos construido el arreglo !ista. El mtodo recorre el ari.eglo y recupera los clatos clel estudiante utilizando los miodos obten"[\ior'hre, obtenCalifieaconcrnso y obtencalificacionExamen. Expresado en pseudocdigo, se tiene lo siguente:
@
efectos de incipal de ajes en el
ror caca elemento i en eL arteglo _7.:sta { imprimir ef nombre de fista[i]; imprimir fas califjcacianes def examen de lista Ii] inprimir fas cafificaciones dej curso de listalil; saltar a Ja siguiente Jnea;
^* ^-J-. ^l -
)
Cmo debe terminar el ciclo? Primero necesitamos darnos cuenta que el arreglo llsta puede estar lleno o no estarlo. Por ejemplo, su tamao predetermnado es 25, pero el nmero real de elementos puede ser menor que 25, de modo que utilizar el valor de la lista.length no funciona. Debido a que lista es un arreglo de objetos, una forma posible de expresar el ciclo es como se muestra a contnuacin:
. while (listalil
i
Un problema con este ciclo wl'ile es que se debe tener por lo menos un elemento vaco en el arreglo para que el ciclo termine correctamente. Esto podemos mejorarlo usando el valor de length como
a& listalil
l= nul1) {
i
Otra posibilidad consiste en mantener un contador, que se fija en el mtodo leepatos. contador es un miembro de datos de tipo int. Esta variable se denominar contadorgstcrda'tes. Entonces, el ciclo de procesamiento se convierte en
Este
748
eaptulo
i3
Herencia y polimorfismo
3.8
jor. Para una salda ms elaborada, puede usarse la tcnica de formateo que se analiz en el
una simple salida como sta, utilizar tabuladores para Ia impresin de resultados funciona me_
cdigo del
paso 2
captulo 6. A continuacin presentamos el Cdigo del paso 2. Observe que aadimos una declaracin para un nuevo miembro de datos co'ltadorEstudartes, y que este miembro de datos se inicializa en 0 en el constructor.
.':x;.:j;::]+:5j
/*
Desarrollo de ejemplo de1 captufo l-3: Calcular calificaciones para estudiant.es no graduados y estudiantes graduados
Archj-vo : CalculaCalif icacion. j ava
r^-
tl
//----
-----pASO 2----
------//
/t
tamani-oArreglo) {
i
Effi
I private void imprimeResultados O { for (nt i = 0; i < cont.adorEstudiantes; i++) { //imprime un estudiante cuadroSalida.print (1isa Ii] .obtenNombre O ) ; for (int, numeroExamen - 1i numeroExamen <= Estudiante.NUlt_OE_UXanUeWfS;
numeroExamen++) {
prueba del
paso 2
cuadroSalida. println )
("
diseo d paso J .
/ /'IEMP
'
3"8
Fjemplo de
desarrollo V49
for (inL i = U; r < 15; r++) t lisLa Iil = new EstudianteNToGraduado O ; lista Ii] .est.abfeceNombre("No graduado # ', + i lista Ii] . estableceCalif icacionExamen (1, 7 +1 lista Ii] . estabLeceCalif icacionExamen (2, gO +lIista Ii] . est.ableceCal- j-f j-cacionExamen (3, 9O +1
O
);
); ); );
for (int i = 15; i < TAMANIO_PREDETERM; j-++) { lista Ii] = new Est.udiantecraduado O ; lista Ii] .estabfeceNombre("Graduado # " + i ); lista Ii] . estableceCalificacionExamen (1, lista Ii] . estableceCalificacionExamen (2, lista Ii] . estableceCalificacionExamen (3,
)
BO
B5 +
90 +
i ); i ); i );
contadorEstudiantes =
TAMANIO pREDETERM;
return true;
prueba del
paso 2
-\-F e
=)
En este paso verificamos dos elementos. En primer lugar, el mtodo temporal leeDatos incluye la creacin de objetos estudiante y llamadas a sus mtodos. Lo ejecucin correcta comprobar que se est incluyendo la clase de estudiantes correcta y que sus mtodos se estn usando adecuadamente. En segundo lugar, el mtodo irnprirneResultados debe mostrar la salida segn se espera. Debido a que no se ha implementado el mtodo calculaCa!ifieacion, para las calificaciones del cursc se vern cuatro asteriscos. Necesitamos ejecutar varias veces el programa y ajustar el formato. Tambin, es importante intentar diferentes valores para los nombres y calificacones de los exmenes antes de proceder al siguiente paso.
::) ) ;
diseo del
paso
.:
La funcionalidad para calcular las calificaciones del curso se encuentra dentro de las clases estudiantes; especficamente, dentro de los mtodos calculaGatificacionCrrso respectivos de las clases EstrdianteGrad.ado y EstudlanteNoGraduado. En consecuencia, todo lo que necestamos hacer en el mtodo calculaCalificaeon es explorar el arreglo lista y llamar a los elementos del mtodo calctlaCalificacon. Esta sencillez es un resultado directo del polimor-
fismo.
75O
Captulo
13
Herencia y polimorfismo
13.8
cdigo del
paso 3
laCalificacion.
Desarrollo de ejemplo del captu1o 13: Calcular las calificaciones Estudiantes no graduados y Estudiantes graduados Archivo : CalculaCal if icacion. j ava
/
de
/ ---
---PAso 3e:<tends
;;,;;;; i
----'//
private vod calculaCalificacionO { for (int i = 0; i < contadorEstudiantes; i++) lista Ii] . calculaCalificacionCurso O ;
)
-1, -
c
n
prueba del
paso 3
Repetimos las mismas rutinas que en el paso 2. En vez de ver los cuatro asteriscos para la calificacin del curso, deberamos ver los valores correctos. Para facilitar la verificacin, es posible fijar las calificaciones para todos los estudiantes. Es necesario asegurarnos de asignar calificaciones de modo que los estudantes estn aprobados o no aprobados. No olvide probar con valores extremos como cero para las califica_ciones.$_e_191r_es e{Te!_es. Qu ocurre con calificaciones negativas? La clase Estudiante las manejara correctamente? Si tenemos graves problemas con la clase Estudiante, puede ser necesario suspender el desarrollo hasta que se
haya corregido esta clase.
13,8
e1
Ejemplo de
desarrollo
751
se
try { fijar
while ( lhecho) { Inea = obtener 7a siguiente 7nea; if (fnea es FrN) { hecho = true; ) else { estudiant.e = creaEstudante(Iinea)
I
W
rara la s posica
if
]
)
)
lifi-
tr con
n calitraveS
ue 5e
,S
eX-
o de Est.dianteNoGnaduado,
dependiendo del tipo especificado en la lnea. 5i en la lnea de entrada hay un error, entonces reaEstudiante devuelve nrll. En vez de terminar todo el programa, simplemente se gnorarn las lneas que no cumplan con el formato especificado.
'
752
Captulo
13
Herencia y polimorfismo
En una forma bastante simplificada, el mtodo creaEstudiante es algo como lo que muestra a continuacin:
se
tipo = primer eTemento de TineaEntrada; if (tipo.equals (No-cRAD) | | tipo.equals (GRAD) ) { estudiante = nuevoEstudianteConDatos ( lineaEntrada else ) { //s" ha enconLrado un L.ipo no v1ido estudiante = null; ]
);
return estudiante,'
(String) el primer elemento. Cm<j puede hacerse esto? El mtodo nuevoEstudianteConDatos, que crea una instancia de EstudianteGraduado o de EstudianteNoGraduado y le asigna datos, tambin requiere una operacin para extraer elementos individuales de la lnea. Podemos escribir nuestra propia rutina de procesamiento de cadenas para analizar la lnea y extraer los datos sobre el tipo, el nombre y las calificaciones de los exmenes. Sin embar!jo, hay una mejor solucin. Podemos utilizar una clase estnda r denorinada StringTokenizer del paquete java.util. Para explicar esta clase haremos una rpida digresin. En vez de usar la clase StringTokenizer, podramos utilizar las tcnicas de correspondencia de patrones con las clases Pattern y Matcher. Sin embargo, la clase StringTokenizer es idnea para un caso como ste, donde se qulere extraer elementos
La primera sentencia requiere extraer de la lnea de entrada
' fokenizer.
sq;in;-
' ,
,
Un objeto de tipo StringTokenizer se utiliza para extraer tokens de una cadena dada. Un token es una cadena de caracteres separada por caracteres delimitadores, o simplemenle delimitadores.Cualquier carcter puede ser designado como delimitador, aunque el delimitador de
mayor uso es el espacio. En forma predeterminada, un objeto de tipo StringTokenizer usa un espacio en blanco (blanco, tabulador, nueva lnea o retorno de carro) como su delimitador. A continuacin se presenta un ejemplo. El cdigo siguiente:
String lineaEntrada = itYo bebo 100 Eazas de caf cada maana."; StringTokeni zer a.nalizador = neyr StringTokenize- (.i.ineaEntrada) while (analizador.hasMoreTokens O ) i ' System.out.prnttn(analizador.nextTokenO ) ;
)
imprimir la siguiente salida:
Yo
bebo
100
Lazas
de
'f
3,8
Ejemplo de
desanollo
7Sg
caf
cada
maana
.
vor, consulte el manual de referencia de'ava.utt para obtener mJs nformacin sobre stnimgT'okenzer.
El mtodo fiasMore'rokens devuelve tnee si en el analizador no quedan ms iokens, y el mtodo nextToken devuelve el siguiente token que est en el analizador. El mtodo nextToken lanza una excepcin f{osuchElenentException si ya no hay ningn token a devolver. porfa-
Cmo
e EstuI
operutina ombre
)a
elcaso, se ha quedado sin suerte. podra terminar programando lu rrn.oJiuJ de StringTokenizer usted mismo, vorviendo a hacer." J. r" zado' Lo anterior siempre constituye un reto pu' todo r mundo, ,or" principiantes. siempre que encuentre una situacin que aparent;;";i;;;;;;; una tarea comn de programacin, primero consulte los manuale,
de Java APt.Tambin puede consulrar con sus
utilizar
a
clase
Ia
zar ias
'go,
entos
,d.
o :ol :, ilsifuctor para efectos de orientacin. euiz eltoi sepan ;d;;;;;; adquirir el hbito de navegar en los rnanuales de referencia ouluuu t', o.;;J; que tenga un conocimiento general sobre las clases estndar. El meollo det asunto consste en buscar clases existentes para reusarlas.
condiscpulor.;;;r"r;.lJn-.'o"
un
elimicr de
;a Lln or. A
Ahora volvamos al diseo. Utilizando un objeto StringTokenizer, el mtodo creaEstrse muestra a continuacin:
tty
{ tipo = analizador.next.TokenO
if (tipo.equals(NO_GRAD) | | tipo.equats(GRAD) ) { estudiante = nuevoEst.ud.j-anteConDat.os (tipo, anal izador) ) else { //=" ha encontrado un tj_po no v1ido estudiante = nul1;
)
return estudi:na.
El mtodo privado nuevoEstudianteconDatos acepta un argumento de tipo string que especifica el tipo de estudiante y un objeto StringTokenizer. El *todo crea una instancia de
: ti
754
Captulo
13
Herencia y polimorfismo
' ..i: .,:)l!:r:i
ri i|!!:l :rr,fi-rr'lri'ii'
'3.8
EstudianteNoGraduado o de EstudianteGraduado y asigna los datos al objeto llamando
manera repetida al mtodo nextToken de StringTokenzer:
de
rrv
/tipo y analizador son los parmetros f (tiPo. equals (NO-GRAD) ) { estudiante = new EstudianteNoGraduado O ; else { ] estudante = new Estudiantecraduado O ;
) estabLecer el nombre deL estudiante //u:-Ilzar {
class I
l
establecer Las calificaciones de7 estud'ian:e ) catch. (Excepcin e) { //genetada por analizador'nextTokeno estudiante = nulI // o Integer'parselnt("')
)
do.ur"nto
privados:
Doturnnt'Ea*iO:' cli'Ca1
Mtddo:i,,'i':,
.:r':
,
uiCii-ricai
:.::
: :i :ia,ji.::.
vsibiidad,
.r)::r,t:l.::::t'
'.
: :-r
::.,
;1':,,:i,r:
.,
i_
::'ou'n'
Le una lnea de datos dl archivo designado a la vez; y para cada lnea de datos, crea un objeto
consLruveLista
l r I r , ,: :t:l .;i
pi'1vate.
ii i
:ii.:.: .r rri.rl..,rr.. ' ii .1::
.:i.:':l i l
, l .
rrriri,,ili,l( lli.:r'l
estudante idneo.5i fos datos en una lnea no se ajustan al formato designado, entonces se lnea. ionora:la ..:
creaEistrudl-anE e : , t,rri
r ll l.l.i.i;ii',rt:il.:i ,. ,:: ,' l :: t. I I :i '1 ..'..
bili+i
I
l,:.rr-l
ri.,..,.,r.1,.11
:.-
.'il
,llr'i
'esiiat
.rl-l.f
I
I
nuevoEstudianteConDatos
li:
p-fivate
. : i::t:r : ii r:
.,.,r,'
ir:
iir;i
Cie un instancia derEstudianteNocra duado o de EstudianteGraduado y asigna datos al objto llamando.de manera repetida a nexLToken de Stringlokeni zer.
*#s
13.8 Ejemplodedesanob
cdigo del paso 4
*;
Desarro]1o de ejemplo de1 captulo 13: Calcular las calificaciones de estudiantes graduados y estud.iantes no graduados Archivo : Calcu1aCalif icacion. j ava
rdor.
j ava. io. * ;
java.util.*;
j avax. swing. *
,.
eno
ltodos
//----- pAso 4 ----:--------// class CalculaCalificacion extends Mai.nWind.ow { private static f nal int TAIvIANIO_PREDETERM = 25; private stat,ic final String NO_GRAD = ,,Nr,. private tatic f inal String GRAD = ',cu privat,e stsatic finaL string FIN_DE_ARCHIVO_STR = ',FIN',; private OutputBox cuadroSalida,. private Estudiante[] lista; private int contadorEstudiantes ; public calculaCalificacionO t thig (TAMANTo_PREDETERM) i
,,
pubLic calculaCalificacion(int tamanioArreglo) t superO; // Llama explcitamente al constructor de Ia superclase cuadroSalida = new OutputBox(this) ; lista = new Estudiante ltamanioArregloj ; contaclorEstudi-antes = 0;
/,/ rrincipal
//----
//---
public static void main(StringlJ args) { Calculacalificacion calculacalif = nw calculaCalificaciono calculaCalif . procesaDatos ( ) ;
)
rF14*
t6
eaptulo
13
Herencia y polimorfismo
3"8
] else {
)
J
archivoEntrada;
FileReader
Buf f eredReader
lectorArchivo; lectorBuf ;
rry {
archivoEnt.rada
lectorArchiwo lectorBuf
new File (nombreArchivo) ; new FileReader (archivoEntrada) ; new Buf f eredReader (lectorArchivo)
while
lhecho) {
DE ARCHIVO STR)
I //
)
)
whil-e
O
;
lectorBuf. close
qP**
13.8
Ejemplo de desarrollo
757
returr estado;
)
private woid calculaCaLificacionO { for (int i = 0; i < contadorEstudiantes; i++) t lista Ii] . calculaCaljficacionCurso O
,.
)
1
private Estudiante creaEstudiante(String linea) { Estudj_ant.e estudiante; StringTokenizer analizador = new StringTokenizer(1inea) String t,ipo; trra { tipo = analizador.nextTokenO ; if (tipo.equals(No_cRAD) I I tipg.equals(GRAD)) {
estudiante = nuevoEstudi"anteConDatos (tipo, analizador) ) else { estudi-ante = nu1l; ) catch (NoSuchElementException e) { estudiante = nu1l;
) )
/
return est.udiante;
f
rry { if
,.
/,/establece:: e1 nombre deI estud.iante String nombre = analizad.or.nextTokenO ; String apellido = analizador.nextTokenO ; estudiante.estableceNombre(nombre + il tr + apellido) ; //estaUtecer 1as calificaciones de1 estudiante for (int numeroExamen =, 1i numeroExamen <= Estudiante.NUM_DE_EXAMENES i numeroExamen++) {
-{&
P58
CaptN.[o
13
Herencia y polimorfismo
t3.8
jr*in.;!'.x.*x;.sr:jri*rj$Fr+):i:Fis{::i;}:4*ja3s+taH:g;*iar.J::1i*t;i:*i}:i*:i;!i::il:+.|jiii*ii!!,j,54 es
'jaii!,ii:,.-a!ij;:
tudiant
e . es
O))
return estudiante;
)
private void imprimeResultados O t for (int i_ = 0,. i < conLadorEstudiantes,. i++) { / /imprimir un estudiante cuadroSalida.print (IisLa Ii] . obtenmombre O ) ; for (int numeroExamen = 1,. numeroExamen <=
Estudiante.NIM_DE_EXAMENES
numeroExamen++) {
cuadrosalida. println
il
\t,
);
private boolean leeDatos O { / /obtener el archivo a abrir ,JFleChooser seLectorArchivo = new ,fFileChooser(". ; ") //empezar 1a lista desde e1 dj-rectorio actuaL int, regresaVal = select.orArchivo. showOpenDialog (this),. boolean resultado = false i if (regresavll ==,fFiIeChooser.AppROVE OPTION) {
s
trins ":t:;::::lll"nr,"
if
)
1e ( )
serAbsolureparh ( ) ;
ffi
*ffi
siguientes:
En este paso ejecutamos una rutina de prueba ms completa. i\jecesitamos ejecu:=: = programa para varios tipos de archivos de entrada. Algunos de los contenidos posibles scn ios
FEop6sito
Probar el caso normal.
:pcin
Archivo con 5 a 20 entradas de informacin del estudiante con todas las lneas en el formato
correcto.
Archivo con 5 a 20 entradas de informacin del estudiante con algunas lneas en formato
tncorrecto.
Probar leeDatos y los mtodos'de soporte para manejar correctamente el caso de error.
+) i
n));
'l
::::
,l
Como siempre, finalizamos el programa corrigiendo los posibles errores inconsistencias o mtodos no terminados. En esta ltima etapa tambin se buscan las posibles mejoras. Una mejora que siempre se busca est relacionada con la longitud de los mtodos. Aunque no hay reglas que especifiquen la longitud, un mtodo no debera ser ms grande que una pgina. Los m_ todos constrtryelista y nuevoEstudianteconDatos se aproximun . urtu mximo. Si observamos que un mtodo se est haciendo ms grande en la etapa de codificacin, entonces necesitamos volver a pensar en el diseo. Por ejemplo, si el mtodo construyeLista se vuelve demasiado grande, entonces podemos definir un nuevo mtodo que lleve a cabo una porcin del mtodo, como desplazar la sentencia if-then-else del mtodo a un nuevo mtodo. Un problema que queda (y que debi identificarse en la prueba del paso 4) es el mtodo faltante para expandir el arreglo tista cuando el archivo de entrada incluye ms entradas de estudiantes que las correspondientes al tamao predeterminado igual a 25. Este mtodo se deja corno elerctcio 3. Tarnbin dejanros con":o ejerclcios algunas de las mejoi-as posibies.
,:Resunrn
La herencia y el polimorfismo son poderosas caractesticas de lenguaje para desarrollar cdigos extensibles y modificabies.
El mecanismo de herencia se utiliza para compartir cdigo comn entre clases re_ lacionadas.
ffi
La herencia es diferente de la interfaz Java, que se utiliza para compartir comporta_ miento comn entre clases no relacionadas.
'6@
Captulo
13
a
a
Herencia y polimorfismo
llamar al constructor en forma predeterminada de ta super"tase. La clase estndar descrita o utilizada en este captulo es
Ei tercer modificador de visibilidad es el modificador protected. En caso de que no se creen instancias_a partir de una superclase, entonces ra super= .; clase debe definirse como una clase abstach. I os mensajes polimrficos indican que el mtodo ejecutado en respuesta al mensa_ je vara segn la clase a qu" p"rten"e el objeto. La primera sentencia en un constructor de una subclase debe ser una llamada al cofistructor de la superclase. si la sentencia requerida no se planteu " **"iul"_ plcifa, entonces el compilador de Java inserta automticamrt" r","n;;;i;;;; - -stringrotenizer.
i'
I I
polimorfismo
herencia contra interfaz
ir
1.
cLass Coche {
marcai peso;
color;
//consEructor de copia public CocheElectrleo (CocheElectrico coche) i this.marca = coche.marca; this.peso coche . peso; this. color = new String(coche.color) ; this.horaRearga = coghe . horaRecarga,.
aF@
Ejercicios 761
class PrlncipalPrueba { pub!.ic static vod main (String[] args) { Coche miCoche; CocheElectrico miCocheElectrico ;
miCoche = new Coche O
mi-Coche.
; ;
miCocheElectrico = nerl CocheElectrico o miCoche.marca = "Chevy"i micoche.peso = 500; micoche. color = "Plateado" ;
]
)
2. Considere las siguientes definiciones de clase. Identifique las llamadas in\'lidas al constructor.
class Coche { public Strlng marca,' protected int peso; private String color; private Coche (String marca, int peso, Strng color) { t,hie.marca = rrrdrCdi this.peso - peso; this.color = color; ) public Coche O i this (rDesconocidorr , -1-, "blancot') ;
]
class CocheElectri-co extende Coche private int horaRecarga; public CocheElectricoO { . this (10) ;
)
public static void main (string Il args) { Coche miCochel, miCoche2; CocheElecLrico miElectricol, miElectrico2;
a;
I
xr.*ffi
762
eaptuf,@
Herenciaypolimorfismo
--\t
, 1200,
r,Verd.e,,) ;
3'
En el programa calculacalificacion se fij el tamao predeterminado del arreglo lista en 25' Modifique el programa de modo que el tamao del arreglo s" incr"meit" si"l archivo de entrada contiene ms de 25 estudiantes. Necesitar irn mtodo qu"
"t
""funurr-"gto ,.
4'
Extienda el programa calculacalificacion para almacenar el arreglo lista utiiizando un objeto de tipo objectoutput5tream. Proporcione a1 usuario la opcin e leer los datos desde un archivo de texto (as es com trabaja el programa original caiculacalificacion) o desde un archivo de objetos. De manera semejinte, proporcione al usuario la opcin de guardar los datos en un archivo de texto un aichivo de objetos.
5'
6"
Modifique el programa de muestra calculacalificacion para introducir los datos desde un archivo de texto utiLzando la clase Scanner envez de las clases FileReader y BufferedReader. IJse el carcter del tabulador (\t) como delimitador.
Cmo debera modificarse el programa CalculaCalificacion si la frmula para calcular la calificacin del curso es diferente para estudiantes de primer ciclo, de segundo ciclo, de tercer ciclo y estudiantes no graduados? disear cuatro Debera subclases de EstudianteNoGraduado? o bien, modificar el cuerpo de mtodo calculaCalificacionCurso de EstudianteNoGraduado? Analice los pros y los contras
de ambos enfoques.
7
'
En el ejemplo de desarrollo del captulo 5 se defini la clase TrazaFigura, que incluye un mtodo para trazar una de tres figuras posibles: un rectngulo-, un rectngulo redondo o una elipse. Modifique esta clase como una superclase de ias tres subclases Rectangle, RoundedRectangle y Ellipse. El trazado ral de una figura se reaiiza con el mtodo TrazaFigura definido en cada una de las tres subclases. Ijtilice la clase auxiliar DrawingBoard del captulo 5 y las cuatro clases definidas en este ejercicio para escribir un programa protector de pantallas que trace 10 rectngulos, 15 rectngulos redondos y 20 elipses de varios tamaos. todas las figuras dJben desplazarse de manera suave en la pantalla.
Ejere ieios de
desarroilo
IJ:*|,?:" oesarTollo,
Para resolver los siguientes ejercicios, aplique Ia metodologa de desarrollo incremental para implementar el programa. Para cada eiercicio, identifilque las tareas del programa, cree el documento de diseo con descripciones de clase y elaore el diagrama --r p1"r"ma' Fscif los pasos del desarrollo al principio. Presenie cualquier altemativa de diseo su seleccin. Asegrese deifeouar pruebas idneai al finar de cada paso ael
Ejercicios
v63
Escriba Lin prograina gestor de finanzas personal que mantenga infolmacin sobfe sus clrentas bancarias. Incorpore ias siguientes regias:
Para 1as cnentas de ahorro, puede hacer un mximo de tres retiros de dinero sin incurrir en ningn gasto. El banco carga $i.00 por cada retiro despus del tercero. Para las cuentas de cheques, ei banco carga $0.50 por cada cheque emitido (es decir, retiros) para 1os primeros 20 cheques en un mes. Despus de eso, no hay cargos.
ndo
los
ulaCa usua-
ltosos des-
Usted debe poder abrir y guardar la informacin de las cuentas en un archivo. Debe poder listar todas las transacciones de una cuenta dada o de todas las cuentas. Incluya 1os mens que considere oportunos para seleccionar las opciones soportadas por e1 programa. Considere el uso de la clase Date para registrar la fecha de las transacciones. La clase Date pertenece al paquete java.util. Por favor, consulte el manual de eferencia java.util para obtener informacin sobre esta clase. 9. Extienda el programa del directorio del captulo 10. En vez de manejar un nico tipo de Persona, incorpore tipos adicionales de pelsonas, como AmigoPersonal y SocioNegocios. Defina estas clases como una subclase de Persona. Elabore un diseo cuidadoso para decidir si la clase Persona debera sel una clase abstracta o no. 10. Considere programa para gestionar cuatro tipos de activos: aparatos electrnicos, automviies, muebies y discos compactos. Qu clase diseara para su programa? y cuatro subclaDefinira las cuatro clases sin relacin o diseara una superciase ses? Si disea una superclase, sera abstracta? 11. Implemente el programa de gestin de activos del ejercicio 10. Pennita al usuario aadir, modificar y borrar apafatos electrnicos, automvi1es, muebles y discos compactos. Permita al usuario enumerar los activos por categora y buscar un deterLtn
:ader y
4 UdI-
de se-
cuatlo
rtodo
onas inclu-ngulo
minado activo por su nmero de serie. t2" lmplemente el programa de gestin de activos del ejercicio 11 aadiendo un objeto
de EiS.
-..:
:bclaealiza
.a
:-.
:
cla-
a::
J.
:jercirs, 15
r des-
:-{
.,, .:,
13. Escriba una apiicacin que lea las temperatulas diarias de 12 meses y permita al usuario obtener estadsticas. Ofrezcapor lo menos tres opciones: media mensual de un mes, media anual y temperaturas mxima y mnima de un mes dado. Utilice un archivo de texto para almacenar las temperaturas. Cada inea del archivo debe contener las temperaturas diarias de un mes. La primera. lnea debe contenei las tempe-
raturas de los das del mes de enero; la segunda, 1as temperaturas cie los das del mes de febrero y as sucesivamente. Utilice un objeto de tipo StringTokenizer para analiza vna lnea con las temperaturas de tipo float. Como esffuctura de datos, considere 1a utilizacin de un arreglo de Mes o un arreglo bidimensional de float. Mes es una clase que usted debe definir.
.:
-ental 'ama,
lgraseo o del