Tema 7.- Fundamentos de la Programación Orientada a Objetos

Anuncio
Tema 7.- Fundamentos de la Programación
Orientada a Objetos
7 de enero de 2014
Objetivos
Saber definir clases propias. Saber crear objetos de una clase determinada e interactuar con ellos
(Problema 1).
Saber añadir constructores a nuestras clases y saber instanciar objetos de acuerdo a los constructores existentes (Problema 2).
Entender el mecanismo de la encapsulación, saber ocultar métodos y/o atributos mediante el modificador private y saber añadir métodos get y set para acceder a atributos privados (Problema 2).
Entender las diferencias entre variables básicas y variables referencia. Saber comparar objetos de
un mismo tipo (Problemas 3, 5 y 6).
Saber implementar métodos que reciban o devuelvan objetos (Problemas 4, 5, 6 y 7).
Saber trabajar con vectores de objetos (Problema 7).
Entender la sobrecarga de métodos y constructores (Problema 8).
Entender los conceptos básicos de la herencia y la sobreescritura de métodos.
Problemas resueltos
A continuación se muestran algunos problemas resueltos en Java que cubren los objetivos anteriores.
1. Escribe una clase que permita representar números complejos y realizar operaciones básicas con
ellos (mostrarlos por pantalla, cálcular el módulo y la fase). Escribe a continuación un programa
principal que cree dos objetos de tipo Complejo, les asigne valores, los muestre por pantalla, y
obtenga el módulo y la fase de cada uno de ellos.
1
2
import j a v a . u t i l . Scanner ;
import j a v a . u t i l . L o c a l e ;
3
4
5
6
7
public c l a s s Complejo {
// A t r i b u t o s
public double r e a l ;
public double imag ;
8
9
10
11
12
// Metodos
public double modulo ( ) {
return Math . s q r t ( r e a l ∗ r e a l + imag ∗ imag ) ;
}
1
13
public double f a s e ( ) {
return Math . atan ( imag / r e a l ) ;
}
14
15
16
17
public void m o s t r a r ( ) {
System . out . p r i n t l n ( r e a l + " + " + imag + "i" ) ;
}
18
19
20
21
}
22
23
24
public c l a s s EjemploComplejo {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
25
// Creamos l o s o b j e t o s c1 y c2
Complejo c1 = new Complejo ( ) ;
Complejo c2 = new Complejo ( ) ;
26
27
28
29
// Pedimos v a l o r e s y l o s almacenamos en l o s o b j e t o s
System . out . p r i n t ( " Introduce parte real del primer numero
complejo : " ) ;
c1 . r e a l = t e c . nextDouble ( ) ;
System . out . p r i n t ( " Introduce parte imaginaria del primer numero
complejo : " ) ;
c1 . imag = t e c . nextDouble ( ) ;
30
31
32
33
34
35
// Pedimos v a l o r e s para c2 y creamos e l o b j e t o
System . out . p r i n t ( " Introduce parte real del segundo numero
complejo : " ) ;
c2 . r e a l = t e c . nextDouble ( ) ;
System . out . p r i n t ( " Introduce parte imaginaria del segundo
numero complejo : " ) ;
c2 . imag = t e c . nextDouble ( ) ;
36
37
38
39
40
41
// Mostrar c1 , su modulo y su f a s e
c1 . m o s t r a r ( ) ;
System . out . p r i n t l n ( " Modulo = " + c1 . modulo ( ) ) ;
System . out . p r i n t l n ( "Fase = " + c1 . f a s e ( ) ) ;
42
43
44
45
46
// Mostrar c2 , su modulo y su f a s e
c2 . m o s t r a r ( ) ;
System . out . p r i n t l n ( " Modulo = " + c2 . modulo ( ) ) ;
System . out . p r i n t l n ( "Fase = " + c2 . f a s e ( ) ) ;
47
48
49
50
}
51
52
}
2. Realiza las modificaciones necesarios en el programa anterior para que:
Los atributos real y imag no puedan ser accedidos directamente desde el programa principal.
El acceso a los atributos se pueda hacer a través de métodos públicos get y set.
En la instanciación (creación) del objeto se pueda especificar el valor de los atributos real
y imag (esto es, que exista un constructor adecuado que pueda recibir como parámetro estos
valores).
2
1
2
import j a v a . u t i l . Scanner ;
import j a v a . u t i l . L o c a l e ;
3
4
5
6
7
public c l a s s Complejo {
// A t r i b u t o s
private double r e a l ;
private double imag ;
8
// C o n s t r u c t o r
public Complejo ( double r , double i ) {
real = r ;
imag = i ;
}
9
10
11
12
13
14
// Metodos
public void s e t R e a l ( double r ) { r e a l = r ; }
15
16
17
public double g e t R e a l ( ) { return r e a l ; }
18
19
public void setImag ( double i ) { imag = i ; }
20
21
public double getImag ( ) { return imag ; }
22
23
public double modulo ( ) {
return Math . s q r t ( r e a l ∗ r e a l + imag ∗ imag ) ;
}
24
25
26
27
public double f a s e ( ) {
return Math . atan ( imag / r e a l ) ;
}
28
29
30
31
public void m o s t r a r ( ) {
System . out . p r i n t l n ( r e a l + " + " + imag + "i" ) ;
}
32
33
34
35
}
36
37
38
39
public c l a s s EjemploComplejo {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
Scanner t e c = new Scanner ( System . i n ) . u s e L o c a l e ( L o c a l e . US) ;
40
41
42
43
44
45
46
// Pedimos v a l o r e s para c1 y creamos e l o b j e t o
System . out . p r i n t ( " Introduce parte real del primer numero
complejo : " ) ;
double r = t e c . nextDouble ( ) ;
System . out . p r i n t ( " Introduce parte imaginaria del primer numero
complejo : " ) ;
double i = t e c . nextDouble ( ) ;
Complejo c1 = new Complejo ( r , i ) ;
47
48
49
50
// Pedimos v a l o r e s para c2 y creamos e l o b j e t o
System . out . p r i n t ( " Introduce parte real del segundo numero
complejo : " ) ;
r = t e c . nextDouble ( ) ;
3
System . out . p r i n t ( " Introduce parte imaginaria del segundo
numero complejo : " ) ;
i = t e c . nextDouble ( ) ;
Complejo c2 = new Complejo ( r , i ) ;
51
52
53
54
// Mostrar c1 , su modulo y su f a s e
c1 . m o s t r a r ( ) ;
System . out . p r i n t l n ( " Modulo = " + c1 . modulo ( ) ) ;
System . out . p r i n t l n ( "Fase = " + c1 . f a s e ( ) ) ;
55
56
57
58
59
// Mostrar c2 , su modulo y su f a s e
c2 . m o s t r a r ( ) ;
System . out . p r i n t l n ( " Modulo = " + c2 . modulo ( ) ) ;
System . out . p r i n t l n ( "Fase = " + c2 . f a s e ( ) ) ;
60
61
62
63
}
64
65
}
3. Indicar lo que mostrarı́a por pantalla la ejecución del siguiente programa:
1
2
3
4
public c l a s s Contacto {
private S t r i n g nombre ;
private S t r i n g e m a i l ;
private S t r i n g t e l e f o n o ;
5
// C o n s t r u c t o r
public Contacto ( S t r i n g nom , S t r i n g em , S t r i n g t e l ) {
nombre = nom ;
e m a i l = em ;
telefono = tel ;
}
6
7
8
9
10
11
12
// Metodos g e t y s e t
public void setNombre ( S t r i n g nom ) { nombre = nom ; }
public S t r i n g getNombre ( ) { return nombre ; }
public void s e t E m a i l ( S t r i n g em ) { e m a i l = em ; }
public S t r i n g g e tE m ai l ( ) { return e m a i l ; }
public void s e t T e l e f o n o ( S t r i n g t e l ) { t e l e f o n o = t e l ; }
public S t r i n g g e t T e l e f o n o ( ) { return t e l e f o n o ; }
13
14
15
16
17
18
19
20
// Metodo m o s t r a r
public void m o s t r a r ( ) {
System . out . p r i n t l n ( " Nombre : " + nombre ) ;
System . out . p r i n t l n ( "e-mail: " + e m a i l ) ;
System . out . p r i n t l n ( " Telefono : " + t e l e f o n o ) ;
System . out . p r i n t l n ( " ====================== " ) ;
21
22
23
24
25
26
27
}
28
29
}
30
31
32
33
public c l a s s EjemploContactos {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
Contacto c1 = new Contacto ( "Luis Garcia " , " lgarcia@gmail .com" ,
" 1234567 " ) ;
4
Contacto c2 = c1 ;
c2 . setNombre ( "Jose Luis Garcia " ) ;
c2 . s e t E m a i l ( " jlgarcia@gmail .com" ) ;
34
35
36
37
System . out . p r i n t l n ( " Contacto 1" ) ;
c1 . m o s t r a r ( ) ;
System . out . p r i n t l n ( " Contacto 2" ) ;
c2 . m o s t r a r ( ) ;
i f ( c1 == c2 )
System . out . p r i n t l n ( "Los contactos 1 y 2 son iguales " ) ;
else
System . out . p r i n t l n ( "Los contactos 1 y 2 son distintos " ) ;
38
39
40
41
42
43
44
45
46
Contacto c3 = new Contacto ( "Jose Luis Garcia " , " jlgarcia@gmail
.com" , " 1234567 " ) ;
System . out . p r i n t l n ( " Contacto 3" ) ;
c3 . m o s t r a r ( ) ;
i f ( c2 == c3 )
System . out . p r i n t l n ( "Los contactos 2 y 3 son iguales " ) ;
else
System . out . p r i n t l n ( "Los contactos 2 y 3 son distintos " ) ;
47
48
49
50
51
52
53
}
54
55
}
SOLUCIÓN:
Contacto 1
Nombre: Jose Luis Garcia
e-mail: [email protected]
Telefono: 1234567
======================
Contacto 2
Nombre: Jose Luis Garcia
e-mail: [email protected]
Telefono: 1234567
======================
Los contactos 1 y 2 son iguales
Contacto 3
Nombre: Jose Luis Garcia
e-mail: [email protected]
Telefono: 1234567
======================
Los contactos 2 y 3 son distintos
4. Tenemos definida la clase Punto del siguiente modo:
public class Punto {
private int x, y;
public Punto (int coordX, int coordY) {
x = coordX;
y = coordY;
}
public int getX() { return (x); }
public int getY() { return (y); }
}
5
Se pretende definir una clase que trabaje con rectas. Como sabemos, una recta r puede representarse mediante la ecuación Ax + By + C = 0, donde, en nuestro problema, los coeficientes A, B y
C serán números enteros. La pendiente de la recta r se define como mr = −A/B. Se pide crear la
clase Recta con los atributos necesarios y las siguientes operaciones:
El constructor, que recibirá como parámetros los coeficientes que definen una recta.
Un método que calcule la pendiente.
Un método que permita saber si dos rectas son paralelas (dos rectas son paralelas si sus
pendientes son iguales).
Un método que permita saber si dos rectas son perpendiculares (dos rectas r y s son perpendiculares si mr = −1/ms ).
Un método que permita saber si un punto (representado mediante un objeto de la clase
Punto) pertenece a una recta (un punto (x, y) pertenece a una recta si Ax + Bx + C = 0).
1
2
3
public c l a s s Recta {
// A t r i b u t o s
private int A, B, C ;
4
// C o n s t r u c t o r
public Recta ( int a , int b , int c ) {
A = a; B = b; C = c ;
}
5
6
7
8
9
// Metodos
double p e n d i e n t e ( ) { return −(A/B) ; }
10
11
12
boolean c o n t i e n e P u n t o ( Punto p ) {
int r ;
r = A∗p . getX ( ) + B∗p . getY ( ) + C ;
return ( r==0) ;
}
13
14
15
16
17
18
boolean p a r a l e l a ( Recta o t r a ) {
return ( p e n d i e n t e ( ) == o t r a . p e n d i e n t e ( ) ) ;
}
19
20
21
22
boolean p e r p e n d i c u l a r ( Recta o t r a ) {
return ( p e n d i e n t e ( ) == −(1/ o t r a . p e n d i e n t e ( ) ) ) ;
}
23
24
25
26
}
5. Añadir un método a la clase Complejo del problema 2 que permita comparar si dos números
complejos son iguales, y otro que permita realizar la suma entre complejos. Los métodos deberán
ser compatibles con el siguiente programa principal:
public static void main(String [] args) {
Complejo c1 = new Complejo(2,3);
Complejo c2 = new Complejo(2,3);
Complejo c3 = c1.suma(c2);
// Suma de complejos
if( c1.equlas(c2) )
// Comparación de complejos
System.out.println("Los complejos c1 y c2 son iguales");
}
6
1
2
3
4
public c l a s s Complejo {
// A t r i b u t o s
private double r e a l ;
private double imag ;
5
// C o n s t r u c t o r
public Complejo ( double r , double i ) {
real = r ;
imag = i ;
}
6
7
8
9
10
11
// Metodo para comparar dos c o m p l e j o s
public boolean e q u a l s ( Complejo c ) {
i f ( r e a l == c . r e a l && imag == c . imag )
return true ;
else
return f a l s e ;
}
12
13
14
15
16
17
18
19
// Metodo para sumar dos c o m p l e j o s
public Complejo suma ( Complejo c ) {
Complejo r e s = new Complejo ( r e a l+c . r e a l , imag+c . imag ) ;
return r e s ;
}
20
21
22
23
24
25
}
6. Añadir un método a la clase Contacto del problema 3 que permita comparar si dos contactos son
iguales.
1
2
3
4
public c l a s s Contacto {
private S t r i n g nombre ;
private S t r i n g e m a i l ;
private S t r i n g t e l e f o n o ;
5
// C o n s t r u c t o r
public Contacto ( S t r i n g nom , S t r i n g em , S t r i n g t e l ) {
nombre = nom ;
e m a i l = em ;
telefono = tel ;
}
6
7
8
9
10
11
12
// Metodos para comparar dos c o n t a c t o s
public boolean e q u a l s ( Contacto c ) {
i f ( nombre . e q u a l s ( c . nombre ) &&
e m a i l . e q u a l s ( c . e m a i l ) &&
telefono . equals ( c . telefono ) )
return true ;
else
return f a l s e ;
}
13
14
15
16
17
18
19
20
21
22
}
7
7. Partiendo de la clase Contacto definida en el problema 3, crear una clase Agenda que permita
almacenar un conjunto de contactos. La clase Agenda deberá disponer de métodos ue nos permitan:
Añadir un nuevo contacto.
Buscar un contacto (a partir del nombre).
Modificar el email de un contacto.
Modificar el telefono de un contacto.
Borrar un contacto.
Mostrar todos los contactos de la agenda.
La clase Agenda deberá ser compatible con el sigiente programa:
1
2
3
public c l a s s Agenda {
// A t r i b u t o s
private Contacto [ ] v ; // Vector que almacena l o s c o n t a c t o s
4
5
6
7
8
9
10
// C o n s t r u c t o r e s
public Agenda ( ) {
// Crea una agenda con c a p a c i d a d para 1000 c o n t a c t o s
// I n i c i a l m e n t e t o d a s l a s r e f e r e n c i a s c o n t i e n e n e l v a l o r ’ n u l l
’
v = new Contacto [ 1 0 0 0 ] ;
}
11
12
13
14
15
16
public Agenda ( int maxContactos ) {
// Crea una agenda con c a p a c i d a d para maxContactos
// I n i c i a l m e n t e t o d a s l a s r e f e r e n c i a s c o n t i e n e n e l v a l o r ’ n u l l
’
v = new Contacto [ maxContactos ] ;
}
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Metodos
/∗ ∗
∗ Busca una p o s i c i o n l i b r e ( n u l l ) en e l v e c t o r y d e v u e l v e d i c h a
posicion ,
∗ o −1 s i e s t a todo ocupado
∗/
private int buscarHueco ( ) {
int pos = 0 ;
while ( pos < v . l e n g t h && v [ pos ] ! = null )
pos++;
i f ( pos < v . l e n g t h )
return pos ;
else
return −1;
}
32
33
34
35
36
37
/∗ ∗
∗ I n s e r t a un nuevo c o n t a c t o en l a agenda . La i n s e r c i o n s e r e a l i z a
en l a p r i m e r a
∗ p o s i c i o n l i b r e que s e e n c u e n t r e en e l v e c t o r
∗/
public boolean i n s e r t a r ( Contacto c ) {
8
int hueco = buscarHueco ( ) ;
i f ( hueco != −1 ) {
v [ hueco ] = c ;
return true ;
}
else
return f a l s e ;
38
39
40
41
42
43
44
45
}
46
47
48
49
50
51
52
53
54
55
56
57
/∗ ∗
∗ Busca un c o n t a c t o a p a r t i r d e l nombre
∗/
public Contacto b u s c a r ( S t r i n g nombre ) {
f o r ( int i = 0 ; i < v . l e n g t h ; i ++) {
i f ( v [ i ] != null )
i f ( nombre . e q u a l s ( v [ i ] . getNombre ( ) ) )
return v [ i ] ; // Devuelve e l c o n t a c t o de l a
posicion i
}
return null ; // No s e ha e n c o n t r a d o e l c o n t a c t o
}
58
59
60
61
62
63
64
65
66
67
68
69
70
/∗ ∗
∗ Dado e l nombre de un c o n t a c t o , m o d i f i c a su e m a i l
∗/
public boolean m o d i f i c a r E m a i l ( S t r i n g nom , S t r i n g em ) {
Contacto c = b u s c a r (nom) ;
i f ( c != null ) {
c . s e t E m a i l (em) ;
return true ;
}
else
return f a l s e ;
}
71
72
73
74
75
76
77
78
79
80
81
82
83
/∗ ∗
∗ Dado e l nombre de un c o n t a c t o , m o d i f i c a su t e l e f o n o
∗/
public boolean m o d i f i c a r T e l e f o n o ( S t r i n g nom , S t r i n g t e l ) {
Contacto c = b u s c a r (nom) ;
i f ( c != null ) {
c . setTelefono ( tel ) ;
return true ;
}
else
return f a l s e ;
}
84
85
86
87
88
89
90
/∗ ∗
∗ Borra de l a agenda t o d o s l o s c o n t a c t o s con e l nombre dado .
∗/
public boolean b o r r a r ( S t r i n g nom ) {
boolean b o r r a d o = f a l s e ;
f o r ( int i = 0 ; i < v . l e n g t h ; i ++) {
9
i f ( v [ i ] ! = null && nom . e q u a l s ( v [ i ] . getNombre ( ) ) ) {
v [ i ] = null ; // Borra e l c o n t a c t o
b o r r a d o = true ;
}
91
92
93
94
}
return b o r r a d o ;
95
96
}
97
98
/∗ ∗
∗ Muestra t o d o s l o s c o n t a c t o s de l a agenda
∗/
public void m o s t r a r ( ) {
f o r ( int i = 0 ; i < v . l e n g t h ; i ++) {
i f ( v [ i ] != null )
v [ i ] . mostrar ( ) ;
}
}
99
100
101
102
103
104
105
106
107
108
}
SOLUCIÓN:
1
import j a v a . u t i l . Scanner ;
2
3
4
5
6
7
8
9
public c l a s s EjemploAgenda {
s t a t i c Scanner t e c = new Scanner ( System . i n ) ;
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
S t r i n g nom , em , t e l ;
Contacto c o n t ;
int opc ;
boolean ok ;
10
11
12
// Creamos n u e s t r a agenda
Agenda ag = new Agenda ( ) ;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
do {
opc = menu ( ) ;
switch ( opc ) {
case 1 :
System . out . p r i n t ( " Nombre : " ) ;
nom = t e c . n e x t L i n e ( ) ;
System . out . p r i n t ( " Email : " ) ;
em = t e c . n e x t L i n e ( ) ;
System . out . p r i n t ( " Telefono : " ) ;
t e l = tec . nextLine () ;
c o n t = new Contacto (nom , em , t e l ) ;
ok = ag . i n s e r t a r ( c o n t ) ;
i f ( ! ok )
System . out . p r i n t l n ( " Agenda llena " ) ;
break ;
case 2 :
System . out . p r i n t ( " Nombre : " ) ;
nom = t e c . n e x t L i n e ( ) ;
c o n t = ag . b u s c a r (nom) ;
10
i f ( c o n t != null )
c o n t . mo s t r a r ( ) ;
else
System . out . p r i n t l n ( "No se ha encontrado ningun
contacto con nombre " + nom) ;
break ;
case 3 :
System . out . p r i n t ( " Nombre del contacto a modificar : " ) ;
nom = t e c . n e x t L i n e ( ) ;
System . out . p r i n t ( " Nuevo email : " ) ;
em = t e c . n e x t L i n e ( ) ;
ok = ag . m o d i f i c a r E m a i l (nom , em) ;
i f ( ! ok )
System . out . p r i n t l n ( "No se ha encontrado ningun
contacto con nombre " + nom) ;
break ;
case 4 :
System . out . p r i n t ( " Nombre del contacto a modificar : " ) ;
nom = t e c . n e x t L i n e ( ) ;
System . out . p r i n t ( " Nuevo telefono : " ) ;
t e l = tec . nextLine () ;
ok = ag . m o d i f i c a r T e l e f o n o (nom , t e l ) ;
i f ( ! ok )
System . out . p r i n t l n ( "No se ha encontrado ningun
contacto con nombre " + nom) ;
break ;
case 5 :
System . out . p r i n t ( " Nombre del contacto a borrar : " ) ;
nom = t e c . n e x t L i n e ( ) ;
ok = ag . b o r r a r (nom) ;
i f ( ! ok )
System . out . p r i n t l n ( "No se ha encontrado ningun
contacto con nombre " + nom) ;
break ;
case 6 :
ag . m o s t r a r ( ) ;
break ;
case 7 :
System . out . p r i n t l n ( " Adios " ) ;
break ;
default : System . out . p r i n t l n ( " Opcion incorrecta " ) ;
}
} while ( opc != 7 ) ;
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
62
63
64
65
66
67
68
69
70
71
72
}
73
74
75
76
77
78
79
80
81
82
public s t a t i c int menu ( ) {
System . out . p r i n t l n ( "1. Insertar contacto " ) ;
System . out . p r i n t l n ( "2. Buscar contacto " ) ;
System . out . p r i n t l n ( "3. Modificar email " ) ;
System . out . p r i n t l n ( "4. Modificar telefono " ) ;
System . out . p r i n t l n ( "5. Borrar contacto " ) ;
System . out . p r i n t l n ( "6. Mostrar todos los contactos " ) ;
System . out . p r i n t l n ( "7. Salir " ) ;
int opc = t e c . n e x t I n t ( ) ;
11
tec . nextLine () ;
return opc ;
83
84
}
85
86
// Vaciamos b u f f e r de t e c l a d o
}
8. Modificar la clase Complejo del problema 2 para que permita:
Sobrecargar el constructor para que permita crear complejos con valores inicializados por
defecto a 1,0 y crear complejos a partir de otro número complejo.
Sobrecargar el método suma para que permita sumar un escalar al número complejo.
1
2
3
4
public c l a s s Complejo {
// A t r i b u t o s
private double r e a l ;
private double imag ;
5
// C o n s t r u c t o r e s
public Complejo ( double r , double i ) {
real = r ;
imag = i ;
}
public Complejo ( ) {
real = 1;
imag = 0 ;
}
public Complejo ( Complejo c ) {
real = c . real ;
imag = c . imag ;
}
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Metodo para sumar dos c o m p l e j o s
Complejo suma ( Complejo c ) {
Complejo r e s = new Complejo ( r e a l+c . r e a l , imag+c . imag ) ;
return r e s ;
}
20
21
22
23
24
25
// Metodo para sumar un e s c a l a r a un c o m p l e j o
Complejo suma ( double x ) {
Complejo r e s = new Complejo ( r e a l+x , imag+x ) ;
return r e s ;
}
26
27
28
29
30
31
}
12
Descargar