Download Recopilación de ejercicios de exámenes

Document related concepts
no text concepts found
Transcript
Ejercicio 1 (parcial 2006). Considere el código de las siguientes clases, cada
una ubicada en un fichero diferente y todas pertenecientes al package Default.
Escriba la salida por pantalla al ejecutar java Main. Se asegura que no
existen errores de compilación.
public class A {
public void f(X arg){
System.out.println("Método f de la clase A");
g(arg);
h();
}
public void g(X x){
System.out.println(x.var);
}
public void g(Z z){
System.out.println("El valor es: " + z.var);
}
public void h(){
System.out.println("Método h de la clase A");
}
}
public class B extends A{
public void f(Z arg){
System.out.println("Método f en clase B");
g(arg);
h();
}
public void h(){
System.out.println("Método h de la clase B");
}
}
public class C extends B{
public void f(Z arg){
System.out.println("Método f1 de la clase C");
}
public void f(X arg){
System.out.println("Método f2 de la clase C");
super.f(arg);
}
}
public class X {
int var;
public X() {
var = 1;
}
}
public class Y extends X{
public Y() {
var = 2;
}
}
public class Z extends Y{
public Z() {
var = 3;
}
}
public class Main {
public static void main(String[] args) {
A objeto;
X argumento;
objeto = new C();
argumento = new Z();
objeto.f(argumento);
}
}
Ejercicio 2 (parcial 2006). Considere la siguiente clase. Escriba la salida por
pantalla al ejecutar java Main. Se asegura que no existen errores de
compilación.
public class MiCadena {
String cadena;
public MiCadena(String s) {
cadena = s;
}
public boolean equals(Object c){
return cadena.equals(c);
}
public String toString(){
return cadena;
}
}
public class Main {
public static void main(String[] args) {
String str1 = "Hola";
String str2 = new String (str1);
String str3 = str1;
MiCadena str4 = new MiCadena("Hola");
MiCadena str5 = new MiCadena(new String("Hola"));
System.out.print("1:");
if (str4.equals(str1)) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("2:");
if (str1.equals(str4)) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("3:");
if (str1.equals(str5.cadena)) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("4:");
if (str4.equals(str5)) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("5:");
if (str2.equals(str1)) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("6:");
if (str1 == str4.cadena) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("7:");
if (str3 == str2) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("8:");
if (str1 == str2) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("9:");
if (str1 == str5.cadena) System.out.println("verdadero");
else System.out.println("falso");
System.out.print("10:");
if (str1 == str4.toString()) System.out.println("verdadero");
else System.out.println("falso");
}
}
Ejercicio 3 (parcial 2006). Responde en una o dos frases a las siguientes
preguntas:
a) ¿Qué se puede hacer con una clase abstracta que no sea posible con una
interfaz?
b) ¿Qué ventaja tienen las interfaces respecto a las clases abstractas?
Ejercicio 4 (parcial 2006). Señala y explica los errores en el siguiente
fragmento de código. Nota: los errores incorrectamente señalados restan 0.1
pts.
interface I {
public void f (C c);
}
class A implements I {
int n;
public void f (A a) {}
}
class B extends A {
static int m;
static final int p = 5;
public void f (B b) {}
public void f (C c) {}
}
abstract class C extends B {
public abstract void g ();
public static void main (String a[]) {
I i;
A x;
B b = new B();
B y;
C c = new C();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
i = b;
x = b;
y = x;
x.f(i);
x.f(x);
x.f(b);
b.f(x);
b.f((C)x);
b.f(b);
b.n = 0;
x.m = 0;
n = 0;
m = 0;
p = 0;
}
}
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Ejercicio 5 (parcial 2006). Dadas las siguientes clases de java, asignar a cada
variable el tipo de acceso más restrictivo posible compatible con una
compilación correcta. Responder en los huecos.
package uno;
public class A{
____________ int x;
____________ int y;
____________ int z;
}
package uno;
public class B {
____________ A a=new A();
B(){
a.x=15;
a.y=17;
}
}
package uno;
public class E extends A {
E(){
x=2;
}
}
package dos;
import uno.*;
public class C extends A {
C(){
y=12;
z=5;
}
}
package dos;
import uno.*;
public class D {
____________ A a=new A();
D(){
a.z=10;
}
}
Ejercicio 6 (parcial 2006). Sean las siguientes clases de java, que se pueden
suponer del mismo paquete:
//=====================================================
class A {
private int x,y;
A(int n1) { [
] }
A(int n1, int n2) { x=n1; y=n2; }
}
//=====================================================
class B extends A {
int z;
B() { [
] z=0; }
B(int n1, int n2) { [
] }
B(int n1, int n2, int n3) { super(n1,n2); z=n3; }
}
//=====================================================
class C extends B {
private int w;
C() {
C(int
C(int
C(int
[
n1)
n1,
n1,
] w=0; }
{ super(n1,0,0); w=0; }
int n2) { [
] w=0; }
int n2, int n3, int n4) { super(n1,n2); z=n3; }
}
En cada uno de los espacios en blanco del código va una de las siguientes
opciones. Indicarlo escribiendo en los huecos la letra correspondiente.
[A]
[B]
[C]
[D]
[E]
super(0);
super(n1,n2);
this(n1,n2,0);
this(n1,0);
Ejercicio 7 (parcial 2007). Considérense las siguientes clases, todas ellas
pertenecientes al paquete empresa:
package empresa;
public class Trabajador
{
private String nombre;
private double sueldo;
public double getSueldo() { return sueldo; }
protected void setSueldo(double s) { sueldo=s; }
public String getNombre() { return nombre; }
public Trabajador(String n, double s)
{
nombre=n;
sueldo=s;
}
}
package empresa;
public class Empleado extends Trabajador
{
private Jefe jefe;
public Jefe getJefe() { return jefe; }
public Empleado(String n, double s, Jefe j)
{
super(n,s);
jefe=j;
jefe.addEmpleado(this);
}
}
package empresa;
import java.util.*;
public class Jefe extends Trabajador
{
private double sueldo;
private ArrayList <Empleado> emps = new ArrayList <Empleado> ();
public void addEmpleado(Empleado e)
{
emps.add(e);
}
public double getSueldo() { return sueldo; }
public void setSueldo(int i, double s)
{
if ((i>=0)&&(i<emps.size())) emps.get(i).setSueldo(s);
}
public Jefe(String n, double s)
{
super(n,s);
}
}
Considérese además la clase Prueba, perteneciente al paquete
predeterminado (default):
import empresa.*;
public class Prueba
{
public static void main(String[] args)
{
Jefe pedro = new Jefe("Pedro",2000.0);
Empleado juan = new Empleado("Juan",1200.0,pedro);
Empleado ana = new Empleado("Ana",1500.0,pedro);
...
}
}
Indíquese si las siguientes afirmaciones son ciertas o falsas, justificando la
respuesta:
1. El objeto pedro puede cambiar el sueldo del objeto juan.
2. El objeto pedro puede cambiar su propio sueldo haciendo lo siguiente:
pedro.addEmpleado((Trabajador)pedro);
pedro.setSueldo(2.5000);
3. El objeto juan puede cambiar su propio sueldo.
4. El objeto juan puede cambiar el sueldo del objeto pedro.
¿Cómo cambiarían las respuestas a las 4 preguntas anteriores si el método
addEmpleado de la clase Jefe estuviera definido de la manera siguiente?
public void addEmpleado(Trabajador e)
{
emps.add((Empleado)e);
}
Volvamos a suponer que las cosas están como al principio. Se desea que el
sueldo de un Jefe sea igual a su sueldo como Empleado incrementado en un
cierto porcentaje o plus. Para ello se añade el método aplicaPlus a la clase
Jefe. Complétese el código de dicho método:
public void aplicaPlus(double plus)
{
}
Suponiendo que el método aplicaPlus funciona correctamente, indíquese cuál
sería el resultado de ejecutar la siguiente lista de instrucciones dentro del
método main de la clase Prueba:
Jefe x = new Jefe("Laura",2000);
System.out.println(x.getNombre()+" "+x.getSueldo());
x.aplicaPlus(0.01);
System.out.println(x.getNombre()+" "+x.getSueldo());
¿Y el resultado de ejecutar esta otra lista de instrucciones?
Jefe x = new Jefe("Laura",2000);
Trabajador t = x;
System.out.println(t.getNombre()+" "+t.getSueldo());
x.aplicaPlus(0.01);
System.out.println(t.getNombre()+" "+t.getSueldo());
¿Por qué no podemos hacer t.aplicaPlus(0.01)?
¿Qué pasa en los dos casos anteriores si no redefinimos el método getSueldo
en la clase Jefe?
Ejercicio 8 (parcial 2007). La siguiente clase AcademiaIngles puede contratar
a un Empleado (hace referencia al problema anterior) si éste sabe inglés y por
tanto puede traducir un String del inglés al español.
public class AcademiaIngles
{
private Traductor x;
public AcademiaIngles(Traductor t)
{
x=t;
}
public String traduceCadena(String s)
{
return x.traduce(s);
}
}
Añadir todo el código necesario para que en el método main de la clase Prueba
podamos hacer lo siguiente:
AcademiaIngles a = new AcademiaIngles(juan);
String esp = a.traduceCadena("Hello");
Nota: no es necesario implementar el método traduce, basta con dejarlo
indicado.
Ejercicio 9 (parcial 2008). Construir las siguientes clases A y B en java:
1. La clase A debe tener un TreeSet de objetos de la clase B y un método
addToTree(B b) que añade el objeto b al TreeSet.
2. La clase B debe cumplir las condiciones necesarias para poder ser
insertada en el TreeSet de A. En particular, contendrá la variable int
clave que se utilizará para establecer el orden de los elementos. Debe
tener un constructor que reciba como argumentos el valor de la clave y
un objeto de la clase A, a cuyo TreeSet se añadirá el objeto recién
construido.
Asignar a todos los campos y métodos el tipo de acceso más restrictivo posible,
suponiendo que las dos clases A y B están en el mismo paquete.
Nota: Se adjunta la documentación relativa a la clase TreeSet y a la interfaz
Comparable.
Ejercicio 10 (parcial 2008). Suponiendo que las siguientes clases e interfaces
están definidas en un package “graphics”:
1
2
3
4
public interface Figure {
double area ();
void move (double x, double y);
}
5
6
7
8
9
10
11
12
13
public class Circle implements Figure {
private double centerX, centerY, radius;
public Circle (double x, double y, double r) throws MalformedFigureException {
if (r < 0) throw new NegativeRadiusException (r);
centerX = x; centerY = y; radius = r;
}
public double area () { return Math.PI * radius * radius; }
public void move (double x, double y) { centerX += x; centerY += y; }
}
14
15
16
17
public class Rectangle implements Figure {
private double left, top, width, height;
public Rectangle (double l, double t, double w, double h)
throws MalformedFigureException {
18
19
20
21
22
23
24
}
25
26
public class MalformedFigureException extends Exception {
}
27
28
public class NegativeSizeException extends MalformedFigureException {
}
29
30
31
32
33
public class NegativeRadiusException extends NegativeSizeException {
private double radius;
protected NegativeRadiusException (double r) { radius = r; }
public String toString () { return radius + " is not valid for a circle radius"; }
}
34
35
36
37
public class NegativeWidthException extends NegativeSizeException {
private double width;
protected NegativeWidthException (double w) { width = w; }
public String toString () { return width + " is not a valid width for a
rectangle"; }
}
38
39
40
41
42
43
if (w < 0) throw new NegativeWidthException (w);
if (h < 0) throw new NegativeHeightException (h);
left = l; top = t; width = w; height = h;
}
public double area () { return width * height; }
public void move (double x, double y) { left += x; top += y; }
public class NegativeHeightException extends NegativeSizeException {
private double height;
protected NegativeHeightException (double h) { height = h; }
public String toString () { return height + " is not a valid height for a
rectangle"; }
}
Dado el siguiente programa:
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
import graphics.*;
class Main {
public static void main (String args[]) {
f (-1, 3, -1);
}
static void f (double r, double w, double h) {
try {
Circle c = new Circle (0, 0, r);
Rectangle rect = new Rectangle (0, 0, w, h);
System.out.println (rect.area ());
}
catch (NegativeRadiusException ex) {
System.out.println ("Negative radius: " + ex);
f (1, 3, -1);
}
catch (NegativeSizeException ex) {
System.out.println ("Negative size: " + ex);
f (1, 3, 1);
}
catch (MalformedFigureException ex) {
System.out.println ("Malformed figure: " + ex);
f (1, 3, 1);
}
System.out.println ("End f");
}
}
a) ¿Cuál es la salida del programa?
b) Si quitamos el primer "catch", ¿cuál sería la salida? ¿Y si quitamos (sólo) el
segundo?
Ejercicio11 (parcial 2008). En el programa del ejercicio anterior, indica si se
produciría algún error, y en tal caso, de qué tipo, en qué línea, y por qué, en
cada uno de los siguientes casos (considerando cada uno separadamente de
los demás):
a) Si quitamos el segundo y tercer “catch”.
b) Si MalformedFigureException no fuese public.
c) Si el constructor de NegativeRadiusException fuese package en vez de
protected.
d) Si Figure no fuese public.
e) Si f no fuese static.
f) Si no implementásemos move en la clase Circle.
g) Si insertamos la siguiente línea:
NegativeSizeException (double value) {}
entre las líneas 27 y 28.
Ejercicio 12 (parcial 2008). Mostrar y explicar la salida del siguiente segmento
de código Java.
class MainClass{
static ArrayList<A> listaAes = new ArrayList<A>();
public static void main(String args[]){
listaAes.add(new A(1));
listaAes.add(new B(2));
Z z = new Z();
for (A proxA: listaAes){
proxA.f();
z.f(proxA);
}
}
}
class A {
int id;
public A(int id){
this.id=id;
}
public void f(){
System.out.println(id);
}
}
class B extends A{
public B(int id){
super(id);
}
public void f(){
System.out.println(id*2);
}
}
class Z{
public void f(A a){
System.out.print("Es un A = ");
a.f();
}
public void f(B b){
System.out.print("Es un B = ");
b.f();
}
}
Ejercicio 13 (parcial 2008). Sean las siguientes clases en java.
abstract class Figura{
private String nombre;
final void imprimirPerimetro(){
System.out.println("Perimetro = " + perimetro());
}
abstract int perimetro();
}
class Rectangulo extends Figura{
int lado1, lado2;
Rectangulo(int l1, int l2){
lado1 = l1;
lado2 = l2;
}
int perimetro(){
return (lado1 * 2 + lado2 * 2);
}
}
Class ConjuntoFiguras{
ArrayList<Figura> figuras = new ArrayList<Figura>();
...
void imprimePerimetros(){
for(Figura f: figuras){
f.imprimirPerimetro();
}
}
}
Crear (y explicar) la clase Cuadrado, que debe cumplir las siguientes
condiciones:
A. El constructor debe recibir sólo un número entero, que representa la
longitud de los 4 lados del cuadrado
B. La llamada c.imprimirPerimetro, donde c es una referencia a una
instancia de la clase Cuadrado, debe imprimir por pantalla el resultado
de (lado * 4).
Ejercicio 14 (junio 2006). El siguiente código corresponde a una aplicación
cliente-servidor en RMI. Rellena los huecos con las sentencias adecuadas para
que funcione correctamente. Como guía, puedes seguir los comentarios en el
código, escritos en negrita. Al manejar las excepciones, usa siempre la clase
más específica posible (no vale usar la clase Exception en todas partes).
Puedes suponer que la dirección del servidor es 150.244.56.56.
import
import
import
import
import
java.util.*;
java.lang.*;
java.rmi.*;
java.rmi.server.*;
java.io.*;
//====================================================================
// Class RandVector
//====================================================================
class RandVector implements RemoteVector{
private int[] v=null;
private Sorter s=null;
// [1] Decide si el constructor tiene que lanzar excepciones:
RandVector() ___________________________________________________ {
// [2] Aquí va una sentencia muy importante para que todo funcione
// bien:
________________________________________________________________;
}
// [3] Decide si el siguiente método tiene que lanzar excepciones:
public void initSorter(Sorter method)___________________________ {
s=method;
}
// [4] Decide si el siguiente método tiene que lanzar excepciones:
public void randInit(int n)_____________________________________ {
v=new int[n];
for (int i=0;i<v.length;i++)
v[i]=(int)(1000*Math.random());
}
// [5] Decide si el siguiente método tiene que lanzar excepciones:
public String getVectorString()_________________________________ {
StringBuffer sb = new StringBuffer();
for (int i=0;i<v.length;i++) sb.append(v[i]+"\t");
return sb.toString();
}
// [6] Decide si el siguiente método tiene que lanzar excepciones:
public void sort ()_____________________________________________ {
// [7] Si el método de ordenación no está definido, lanzamos una
//
NoSortingMethodException:
if (s==null) __________________________________________________;
else s.sort(v);
}
}
//====================================================================
// Interface Sorter:
//====================================================================
// [8] Escribe la cabecera de la interfaz Sorter:
____________________________________________________________________ {
// [9] Decide si el siguiente método tiene que lanzar excepciones:
public void sort(int[] v)________________________________________;
}
//====================================================================
// Class CutreSort:
//====================================================================
class CutreSort implements Sorter
{
public void sort(int[] v)
{
for (int i=0;i<(v.length-1);i++)
for (int j=(i+1);j<(v.length);j++)
if (v[j]<v[i])
{
int aux=v[i];
v[i]=v[j];
v[j]=aux;
}
}
}
//====================================================================
// Class NoSortingMethodException:
//====================================================================
// [10] Escribe el código de la clase NoSortingMethodException:
//====================================================================
// Interface RemoteVector:
//====================================================================
// [11] Escribe la cabecera de la interfaz RemoteVector:
____________________________________________________________________ {
// [12] Decide si los siguientes métodos tienen que lanzar
// excepciones:
public void initSorter(Sorter method)____________________________;
public void randInit(int n)______________________________________;
public String getVectorString()__________________________________;
public void sort ()______________________________________________;
}
//====================================================================
// Class VectorServer:
//====================================================================
class VectorServer {
// [13] Decide si el siguiente método tiene que lanzar
// excepciones:
public static void main (String args[])_________________________ {
if (System.getSecurityManager()==null)
System.setSecurityManager(new RMISecurityManager());
// [14] Crea un nuevo RandVector y regístralo en el servidor de
// nombres:
_______________________________________________________________;
_______________________________________________________________;
}
}
//====================================================================
// Class VectorClient:
//====================================================================
class VectorClient {
// [15] Decide si el siguiente método tiene que lanzar
// excepciones:
public static void main (String args[])_________________________ {
if (System.getSecurityManager()==null)
System.setSecurityManager(new RMISecurityManager());
try {
// [16] Crea el stub sv y obtén la referencia a RandVector:
___________________________________________________________;
sv.randInit(8);
sv.initSorter(new CutreSort());
System.out.println("Original:\t"+sv.getVectorString());
sv.sort();
System.out.println(" Sorted:\t"+sv.getVectorString());
}
// [17] Escribe todos los bloques catch que sean necesarios:
}
}
Ejercicio 15 (junio 2006). Muestra la salida del siguiente programa:
interface X {
public void f (X x);
public void f (B a);
}
class A implements X {
int m[];
public void f (X a) { System.out.println ("AX"); }
public void f (B a) { System.out.println ("AB"); }
}
class B extends A {
B () { m = new int[1]; m[0] = 1; }
public void f (X a) { System.out.println ("BX"); }
public void f (B a) { System.out.println ("BB"); }
}
class Main {
public static void main (String args[]) {
A a = new A ();
B b = new B ();
X x = a, y = b;
x.f (x);
x.f (b);
y.f (y);
g (b.m);
System.out.println (b.m[0]);
g (a.m);
System.out.println (a.m[0]);
}
static void g (int m[]) { m[0] = 2; }
}
Ejercicio 16 (junio 2006). Dado el siguiente código:
import java.awt.*;
import java.awt.event.*;
class ToggleCase implements MouseListener {
Sign sign;
ToggleCase (Sign s) {
Sign = s;
((Component) s) .addMouseListener (this);
}
public void mouseClicked (MouseEvent ev) {
if (sign.getMsg() .equals ("On"))
sign.setMsg ("Off");
else sign.setMsg ("On");
}
public void mouseEntered (MouseEvent ev) {}
public void mouseExited (MouseEvent ev) {}
public void mousePressed (MouseEvent ev) {}
public void mouseReleased (MouseEvent ev) {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CanvasSign extends Canvas {
String msg;
CanvasSign (String str) {
setMsg (str);
new ToggleCase (this);
}
public String getMsg () { return msg; }
public void setMsg (String str) {
msg = str;
repaint ();
}
public void paint (Graphics g) {
g.drawString (msg, 0, 20);
}
}
class LabelSign extends Label {
LabelSign (String str) {
setMsg (str);
setBackground (Color.blue);
new ToggleCase (this);
}
public String getMsg () { return getText (); }
public void setMsg (String str) { setText (str); }
}
class Ventana extends Frame {
Ventana () {
setSize (300, 200);
add ("North", new LabelSign ("Off"));
add ("Center", new CanvasSign ("Off"));
}
public static void main (String a[]) {
new Ventana () .setVisible (true);
}
}
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
a) Completar el código de forma que compile y ejecute correctamente.
b) Mostrar la interfaz que se ve en pantalla al arrancar el programa (una
vez completado).
c) Mostrar el estado de la interfaz después de hacer click sobre el label y
click sobre el canvas (mostrar sólo el estado final).
d) Indica con precisión como sería la respuesta a la pregunta c en cada
uno de los siguientes casos (independientemente uno de otro). En caso
de error, indicar de qué tipo (compilación o ejecución, clase de
excepción, etc.), en qué línea, y por qué.
i.
ii.
iii.
iv.
v.
Si se comenta la línea 7.
Si se comenta la línea 8.
Si se quita el cast a Component en la línea 8.
Si se comenta la línea 15.
Si se comenta la línea 30.
Ejercicio 17 (junio 2006). Considera el siguiente código en java:
class MyThread extends Thread {
String str; X obj;
MyThread (String s, X x) {
str = s;
obj = x;
}
public void run () {
f (obj);
g (obj);
h (obj);
}
synchronized void f (X obj){
obj.f(str);
}
synchronized void g (X obj){
obj.g(str);
}
synchronized void h (X obj){
obj.h(str);
}
public static void main (String a[]) {
X x = new X (), y = new X ();
new MyThread ("A", x).start ();
new MyThread ("B", x).start ();
new MyThread ("C", y).start ();
}
}
class X {
synchronized void f (String s)
System.out.print (" f" + s
System.out.print (" f" + s
}
synchronized void g (String s)
System.out.print (" g" + s
System.out.print (" g" + s
}
void h (String s) {
System.out.print (" h" + s
System.out.print (" h" + s
}
}
{
+ "-in");
+ "-out");
{
+ "-in");
+ "-out");
+ "-in");
+ "-out");
Decir si cada una de las siguientes salidas es teóricamente posible, explicando
en una frase por qué.
a) fA-in fA-out gA-in gA-out hA-in fB-in hA-out fB-out
...
b) fA-in fA-out gA-in fB-in fB-out gA-out ...
c) fA-in fB-in fB-out fA-out ...
d) fA-in fC-in fC-out fA-out ...
Ejercicio 18 (junio 2006).
a) Implementar una clase Conjunto que contenga por lo menos:
− Una lista de objetos de cualquier tipo.
− No pueden existir valores repetidos.
− Un constructor, que reciba un argumento de tipo Collection, y
cree un Conjunto que contenga esos elementos.
Cuidado: en la colección recibida como argumento puede haber
elementos repetidos.
− Un método interseccion que tome como argumento otro
Conjunto, y devuelva un nuevo Conjunto con la intersección
de los dos, es decir, los elementos de la primera lista que son
equals a algún elemento de la segunda.
b) Implementar una clase Estudiante con una variable
numMatricula y los métodos necesarios para que se pueda hacer la
interseccion de listas de estudiantes con la clase anterior,
considerando que dos estudiantes son el mismo cuando tienen el mismo
numMatricula.
Ejercicio 19 (septiembre 2006). El siguiente código java corresponde a una
aplicación cliente-servidor en RMI que implementa un chat. Algunos
comentarios en el código indican partes incompletas. Responde a las
preguntas del final.
import
import
import
import
import
java.util.*;
java.lang.*;
java.io.*;
java.rmi.*; import java.rmi.server.*;
java.awt.*; import java.awt.event.*;
// [1] Definir interfaces...
class Cliente extends Frame implements ActionListener, ClienteRemoto {
private ChatRemoto chat;
private Panel p1, p2;
private TextArea ta;
private TextField tf;
private String name;
public Cliente (String nombre) throws Exception {
name = nombre;
p1 = new Panel();
ta = new TextArea(15,60);
ta.setEditable (false);
p1.add (ta);
add ("Center",p1);
p2 = new Panel();
tf = new TextField(60);
tf.addActionListener(this);
p2.add (tf);
add ("South",p2);
this.addWindowListener (new CerrarCliente ());
// [2] Completar constructor...
}
public void actualizar (String texto) throws RemoteException {
ta.append(texto);
}
public String getNombre () throws RemoteException {
return this.name;
}
public void actionPerformed (ActionEvent e) {
// [3] Rellenar método...
}
class CerrarCliente extends WindowAdapter {
public void windowClosing (WindowEvent e) {
Cliente c = (Cliente) e.getSource ();
try { chat.eliminarClienteChat (c); System.exit(0); }
catch (RemoteException ex) { ex.printStackTrace(); }
}
}
public static void main (String args[]) {
try {
Cliente c = new Cliente (args[0]);
c.setSize(480,350);
c.setVisible (true);
} catch (Exception e) { e.printStackTrace (); }
}
}
class Chat extends UnicastRemoteObject implements ChatRemoto {
private ArrayList clientes = new ArrayList ();
public Chat () throws RemoteException { }
public synchronized void enviarMensajeChat (ClienteRemoto c, String texto)
throws RemoteException {
Iterator it = clientes.iterator ();
while (it.hasNext ())
((ClienteRemoto) it.next ()).actualizar (" > " + c.getNombre() + " dice: "
+ texto);
}
public void registrarClienteChat (ClienteRemoto c) throws RemoteException {
clientes.add (c);
}
public void eliminarClienteChat (ClienteRemoto c) throws RemoteException {
clientes.remove (c);
}
}
class Servidor {
// [4] Rellenar código...
}
1. En relación al comentario [1], definir las interfaces que sean necesarias.
2. En relación al comentario [2], completar el constructor de la clase Cliente.
3. En relación al comentario [3], escribir el código del método
actionPerformed en la clase Cliente para que cuando el usuario pulse
enter el texto en el TextField se envíe a los demás usuarios del chat.
4. En relación al comentario [4], escribir el código de la clase Servidor.
5. Cómo compilarías el código, suponiendo que está todo en un fichero llamado
clases.java.
6. ¿Qué clases se crean? ¿Cuáles ubicarías en el cliente y cuáles en el
servidor?
7. ¿Qué pasaría si el método enviarMensajeChat de la clase Chat no fuera
synchronized?
Ejercicio 20 (septiembre 2006). Responder a las siguientes cuestiones:
1. ¿Qué es una excepción?
2. ¿Qué tipos de excepciones hay?
3. ¿Qué se puede hacer con las excepciones?
4. Citar al menos tres ventajas de las excepciones sobre el tratamiento usual
de errores.
Ejercicio 21 (septiembre 2006). Dado el siguiente programa:
import java.awt.*;
import java.awt.event.*;
abstract class Operator {
String label;
Operator (String str) { label = str; }
public String toString () { return label; }
abstract String operate (String inputs[]);
}
class MinStr extends Operator {
MinStr () { super ("min"); }
String operate (String inputs[]) {
String min = inputs[0];
for (int i = 1; i < inputs.length; i++)
if (inputs[i] .compareTo (min) < 0) min = inputs[i];
return min;
}
}
class OperatorPanel extends Panel implements ActionListener {
Operator operator;
TextField inputPanels[];
String inputs[];
Label output;
OperatorPanel (Operator op, int n) {
operator = op;
inputs = new String[n];
1
2
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
inputPanels = new TextField[n];
for (int i = 0; i < n; i++) {
inputPanels[i] = new TextField (String.valueOf (i));
add (inputPanels[i]);
}
Button doButton = new Button (operator.toString ());
add (doButton);
doButton.addActionListener (this);
output = new Label ();
add (output);
}
public void actionPerformed (ActionEvent ev) {
for (int i = 0; i < inputPanels.length; i++)
inputs[i] = inputPanels[i].getText ();
output.setText (operator.operate (inputs));
}
}
class MyWindow extends Frame {
MyWindow () {
setBounds (100, 100, 300, 200);
add ("North", new OperatorPanel (new MinStr (), 3));
}
public static void main (String a[]) {
new MyWindow () .setVisible (true);
}
}
1. Dibujar con detalle la interfaz de usuario que se genera al ejecutar el
programa, después de pulsar el botón que contiene la interfaz.
2. Al programa anterior añadimos la siguiente subclase:
class MySubWindow extends MyWindow {
MySubWindow () {
add ("South", new OperatorPanel (new Sum (), 3));
}
public static void main (String a[]) {
new MySubWindow () .setVisible (true);
}
}
Definir la clase Sum de forma que la clase MySubWindow compile y se ejecute
correctamente, y el programa resultante sirva para sumar números.
3. Dibujar con detalle la interfaz de usuario que se genera al ejecutar y pulsar
todos los botones que contenga la interfaz del programa definido por la clase
del apartado anterior.
Ejercicio 22 (septiembre 2006). En el programa del ejercicio anterior (con el
añadido del apartado 3):
1. ¿Qué sucedería si…?
vi. Se comenta la línea 12.
vii. Se cambia la línea 27 por Operator operator = op;
Responde con precisión, razonando brevemente las respuestas.
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
2. Describe brevemente pero con precisión qué habría que cambiar en el
código para que Operator pudiera ser una interface en lugar de una clase
abstracta.
3. Supongamos que las clases Operator, MinStr y Sum se colocan en un
package operators, y que el resto de las clases se dejan en el
DefaultPackage. ¿Cuál sería la declaración de control de acceso (public,
private, etc.) más restrictiva posible que podría aplicarse a los siguientes
elementos, sin provocar errores de compilación?
i. La clase Operator.
ii. La variable label de la clase Operator.
iii. El método operate en la clase Operator.
iv. El constructor de OperatorPanel.
v. El constructor de MinStr.
Ejercicio 23 (septiembre 2006). Dado el siguiente código, haga todos los
cambios necesarios para que cada instancia de CajeroAutomático ejecute en
hilo separado de forma segura.
class CuentaBancaria {
long numero;
long saldo;
void ingresar (long cantidad) {
saldo += cantidad;
}
void retirar (long cantidad) {
if (cantidad > saldo)
System.out.println ("Saldo insuficiente");
else saldo -= cantidad;
}
}
class CajeroAutomático {
void ingresar (CuentaBancaria cb, long cantidad){
cb.ingresar(cantidad);
}
void retirar (CuentaBancaria cb, long cantidad){
cb.retirar(cantidad);
}
}
class Banco {
public static void main (String [] args){
CuentaBancaria cb1, cb2, cb3;
CajeroAutomático ca1, ca2, ca3;
cb1 = new CuentaBancaria();
cb2 = new CuentaBancaria();
cb3 = new CuentaBancaria();
ca1 = new CajeroAutomático();
ca2 = new CajeroAutomático();
ca3 = new CajeroAutomático();
}
}
Ejercicio 24 (septiembre 2006). El siguiente método ordena una lista de
números decimales por el método de la burbuja:
static void ordenar (double lista[]) {
for (int i = 0; i < lista.length-1; i++)
for (int j = lista.length; j > i; j--)
if (lista[j] < lista[j-1]) intercambiar (lista, j, j-1);
}
a) Generalizar la función ordenar para que ordene listas de cualquier tipo
de datos sobre los que tenga sentido definir una relación de orden. Para
ello, introducir una mínima modificación en las líneas 1 y 4, y definir las
clases y/o interfaces adicionales que sean necesarias.
b) Basándose en el diseño del apartado anterior, definir las clases
Rectangulo, Circulo y Figura, de tal manera que sea posible
ordenar listas de figuras por su área. Definir en estas clases todos los
métodos y variables necesarios para ello, siempre al nivel más alto
posible de la jerarquía de clases.
Nota: para simplificar, se permite suponer que los lados de un
Rectangulo son paralelos a los ejes de coordenadas.
Ejercicio 25 (junio 2007). Considérense las siguientes clases:
public class Trabajador
{
private String nombre;
private double sueldo;
public double getSueldo() { return sueldo; }
public void setSueldo(double s) { sueldo=s; }
public String getNombre() { return nombre; }
public Trabajador(String n, double s) {
nombre=n;
sueldo=s;
}
}
public class Empleado extends Trabajador
{
private Jefe jefe;
public Jefe getJefe() { return jefe; }
public Empleado(String n, double s, Jefe j) {
super(n,s);
jefe=j;
jefe.addEmpleado(this);
}
}
1
2
3
4
public class Jefe extends Trabajador
{
private ArrayList <Empleado> emps = new ArrayList <Empleado> ();
public void addEmpleado(Empleado e) {
emps.add(e);
}
public void setSueldo(int i, double s) {
if ((i>=0)&&(i<emps.size())) emps.get(i).setSueldo(s);
}
public Jefe(String n, double s) {
super(n,s);
}
}
Se pide:
1. Modificar las clases Empleado y Jefe, y añadir el código que sea necesario
para que empleado y jefe puedan correr en máquinas distintas. No hay que
modificar la clase Trabajador.
2. Escribir un método main para la clase Empleado, que haga lo siguiente:
-
Obtener la referencia a un jefe llamado “Pedro” en la máquina
“cron.uam.es”
Crear un empleado con nombre “Juan”, sueldo 2000 y el jefe anterior.
Imprimir el sueldo del empleado Juan en el momento en que su jefe
le suba el sueldo.
3. ¿Sería posible hacer todo lo anterior con una clase Empleado que fuera
Serializable?
Ejercicio 26 (junio 2007). Crear una nueva clase de excepción llamada
MyException. Crear una clase A con dos métodos f y g. El método g debe
lanzar una excepción de la clase anterior. El método f debe llamar al método g
y capturar la posible excepción, imprimiendo la traza de la pila.
Ejercicio 27 (septiembre 2007). En una aplicación cliente-servidor
programada con java rmi, el servidor (cron.uam.es) actúa como una máquina
de computación que permite ejecutar de forma remota tareas arbitrarias. Se
han programado las siguientes clases:
import java.rmi.*;
public interface Tarea extends java.io.Serializable {
Object ejecutar ();
}
import java.rmi.*;
public interface MaquinaRemota extends Remote {
Object ejecutarTarea (Tarea t) throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class MaquinaComputacion extends UnicastRemoteObject implements
MaquinaRemota {
public MaquinaComputacion () throws RemoteException {}
public Object ejecutarTarea (Tarea t) throws RemoteException {
return t.ejecutar ();
}
}
import java.rmi.*;
public class Servidor {
public static void main(String[] args) {
if (System.getSecurityManager () == null)
System.setSecurityManager (new RMISecurityManager());
try {
MaquinaComputacion maq = new MaquinaComputacion ();
Naming.rebind ("maquina", maq);
System.out.println ("Maquina lista");
}
catch (Exception e) { e.printStackTrace(); }
}
}
Queremos programar un cliente que utilice esta máquina de computación para
ordenar listas de números enteros. Las listas serán implementadas como
ArrayList de Integer. Se pide:
1. Escribir el código de la clase OrdenarLista, que implementará la
interfaz Tarea. Esta clase se utilizará para ordenar listas de números
enteros en el servidor. Puede usarse el método sort de la clase
Collections.
2. Escribir el código de la clase Cliente, que debe hacer lo siguiente:
a. Crear un ArrayList de 20 Integer, e inicializarlo con valores
aleatorios entre 0 y 9999 (usar el método random de la clase
Math).
b. Obtener la referencia a la máquina de computación remota.
c. Ordenar la lista en el servidor utilizando un objeto de la clase
OrdenarLista creada antes.
3. ¿Para qué sirve la llamada al método setSecurityManager en la
clase Servidor?
Ejercicio 28 (septiembre 2007). ¿Cuál es la salida del siguiente programa?
class Punto3D {
double x, y, z;
Punto3D (double xx, double yy, double zz) { x = xx; y = yy; z = zz; }
}
class Esfera {
Punto3D centro;
double radio;
Esfera (Punto3D p, double r) { centro = p; radio = r; }
public boolean equals (Object obj) {
if (!(obj instanceof Esfera)) return false;
Esfera e = (Esfera) obj;
return centro.equals (e.centro) && radio == e.radio;
}
}
class Plano3D {
double a, b, c, d;
Plano3D (double aa, double bb, double cc, double dd) { a = aa; b = bb; c =
cc; d = dd; }
public boolean equals (Plano3D p) {
return a * p.b == b * p.a && a * p.c == c * p.a && a * p.d == d * p.a;
}
}
class Main {
public static void main (String a[]) {
Punto3D x = new Punto3D (0, 0, 0);
Plano3D p = new Plano3D (2, 0, -2, 4);
Plano3D q = new Plano3D (3, 0, -3, 6);
Esfera e = new Esfera (x, 3);
Esfera f = new Esfera (x, 3);
Esfera g = new Esfera (new Punto3D (0, 0, 0), 3);
System.out.println (p.equals (q));
System.out.println (e.equals (f));
System.out.println (e.equals (g));
java.util.ArrayList lista = new java.util.ArrayList ();
lista.add (f);
lista.add (g);
lista.add (p);
lista.add (q);
System.out.println (lista.lastIndexOf (p)); // lastIndexOf devuelve la
posición de la
System.out.println (lista.lastIndexOf (e)); // última aparición del
objeto en la
}
// lista (-1 si no aparece).
}
Ejercicio 29 (septiembre 2007). Dado el siguiente programa:
import java.awt.*;
import java.awt.event.*;
abstract class Operation {
String symbol;
Operation (String str) { symbol = str; }
public String toString () { return symbol; }
abstract String compute (String inputs[]);
}
class MaxStr extends Operation {
MaxStr () { super ("max"); }
String compute (String inputs[]) {
String max = inputs[0];
for (int i = 1; i < inputs.length; i++)
if (inputs[i] .compareTo (max) > 0) max = inputs[i];
return max;
}
}
class OperationPanel extends Panel implements ActionListener {
Operation operation;
TextField inputFields[];
String inputs[];
Label output;
OperationPanel (Operation op, int n) {
operation = op;
inputs = new String[n];
inputFields = new TextField[n];
for (int i = 0; i < n; i++) {
inputFields[i] = new TextField (String.valueOf (i+1));
add (inputFields[i]);
}
Button doButton = new Button (operation.toString ());
add (doButton);
doButton.addActionListener (this);
output = new Label ();
add (output);
}
public void actionPerformed (ActionEvent ev) {
for (int i = 0; i < inputFields.length; i++)
inputs[i] = inputFields[i].getText ();
output.setText (operation.compute (inputs));
}
}
class MyWindow extends Frame {
MyWindow () {
setBounds (100, 100, 300, 200);
add ("North", new OperationPanel (new MaxStr (), 3));
}
public static void main (String a[]) {
new MyWindow () .setVisible (true);
}
}
a) Dibujar con detalle la interfaz de usuario que se genera al ejecutar el
programa, después de pulsar el botón que contiene la interfaz.
b) Al programa anterior añadimos la siguiente subclase:
class MySubWindow extends MyWindow {
MySubWindow () {
add ("South", new OperationPanel (new Product (), 3));
}
public static void main (String a[]) {
new MySubWindow () .setVisible (true);
}
}
Definir la clase Product de forma que la clase MySubWindow compile y se
ejecute correctamente, y el programa resultante sirva para multiplicar
números.
c) Dibujar con detalle la interfaz de usuario que se genera al ejecutar y pulsar
todos los bo-tones que contenga la interfaz del programa definido por la
clase del apartado anterior.
Ejercicio 30 (septiembre 2007). Escriba las clases Java necesarias para
representar los siguientes conceptos. Para aquellas que se especifique,
también debe implementar los servicios requeridos, cuidando de que esta
implementación cumpla con las especificaciones requeridas (por ejemplo, no
mezclar palabras de distinta lengua cuando no corresponda).
Letra: cualquiera de las letras del alfabeto latino.
Palabra: compuesta por una secuencia de letras, posiblemente repetidas. Está
asociada con una lengua determinada.
•
Servicios:
•
Constructor, que reciba lista de letras.
Frase: secuencia de palabras, todas de la misma lengua.
•
Servicios:
•
Constructor, que reciba lista de palabras.
Párrafo: secuencia de frases, todas con palabras de la misma lengua.
Diccionario: obra de consulta de palabras que se encuentran ordenadas
alfabéticamente (es decir, está compuesto de una secuencia de palabras).
•
Servicios:
•
Constructor, que permita especificar la lengua de las palabras del
diccionario.
•
agregarPalabra: función que permita agregar una nueva palabra al
diccionario, junto con la información asociada.
Diccionario de la Lengua: en ellos se explica brevemente el significado de las
palabras de una lengua determinada. Cada palabra tiene asociada uno o más
definiciones.
Diccionario de Idioma: diccionarios en que, dada un secuencia de palabras
en una lengua determinada, se indican las palabras equivalentes en otra
lengua.
Diccionario de Sinónimos: lista de palabras (pertenecientes a una lengua
determinada), para cada una de las cuales se ofrecen otras palabras (de la
misma lengua) con significado similar.
Definición: uno o más párrafos describiendo el significado de una palabra.
Sinónimo: relación entre dos palabras que comparten una o más
definiciones.
Lengua: para los fines de este ejercicio, simplemente se considerará que una
lengua está representada por su nombre (por ejemplo, “Español”, “Inglés”,
“Francés”).
Para todo aquello que no esté especificado, utilice la interpretación que se
derive del uso cotidiano y sentido común de estos términos.
Ejercicio 31 (septiembre 2006).
a) Explica brevemente la diferencia entre un método synchronized y otro que
no lo es.
b) Muestra y explica un ejemplo donde es útil utilizar más de un hilo en Java.