Corso di Laurea in Informatica

Programmazione

M. A. Alberti
Università degli Studi di Milano
A.A. 2005/06

Soluzioni prova scritta - IV appello 12 luglio 2006

Esercizio 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

Esercizio 1

Risposte
  1. Output del I ciclo for:
    1
    2
    i: 3 // all'uscita dal ciclo
  2. Output del II ciclo for:
    1
    2
    4
    5
    7
    8
    i: 10 // all'uscita dal ciclo
  3. Output del III ciclo for:
    1
    2
    // il programma si interrompe senza eseguire la stampa fuori dal ciclo

Si veda il programma BreakExit.java

Esercizio 2

Risposta
  1. Sì, un oggetto di classe BarcaVela avrà i metodi citati perchè li eredita dalla superclasse, così come potrà avere disponibili altri metodi eventualmente definiti nella classe.
  2. Non necessariamente. Se la classe derivata non ridefinisce il metodo, allora questo avrà lo stesso comportamento, cioè compierà le stesse azioni nella classe derivata come nella classe base. Se la classe derivata ridefinisce il metodo specializzandolo agli oggetti della propria classe allora questa nuova definizione sostituisce quella ereditata dalla superclasse.
  3. Il meccanismo descritto nella risposta precedente si chiama sovrascrittura di metodi. I metodi sovrascritti dovranno avere lo stesso numero e tipo di parametri.
  4. No, perché i metodi definiti per la classe derivata non sono disponibili agli oggetti della superclasse.

Esercizio 3

Risposte
  1. Si, è possibile.
  2. Il membro nome è dichiarato private, e può essere modificato solo all'interno della classe che lo definisce oppure da metodi pubblici della classe in questione dopo che l'oggetto è stato generato. Quindi è necessario definire un metodo dichiarato public che invocato su un oggetto già generato potrà accedere al membro privato.
    public void modificaNome (String nuovoNome)
    {
       nome = nuovoNome;
    }
    
    Il metodo potrà essere invocato come segue:
    Dipendente dip = new Dipendente ("Carlo");
    dip. modificaNome("Carlo Rossi");
    
  3. La sottoclasse Impiegato che estende la classe Dipendente dovrà avere i costruttori così corretti:
    class Impiegato extends Dipendente
    {
       private int settore; // 1, 2, 3 ad esempio
       Impiegato() 
       {
          super();
          settore = 1; // valore di default
       }
       Impiegato(String unNome, int unSettore) 
       {
          super(unNome);
          settore = unSettore;
       }
    }
    
  4. È possibile accedere al membro nome della superclasse, ma non direttamente perchè non viene ereditato in quanto dichiarato privato.
  5. L'espressione imp.nome per accedere al campo nome non è corretta perchè il campo nome è privato, come si è detto. Una variabile d'istanza dichiarata privata in una classe base non è accessibile direttamente invocandola per nome, neppure nella definizione di metodi della classe derivata, ma solo tramite metodi pubblici della classe base, se ci sono.
  6. Si potrà quindi usare un metodo dichiarato pubblico nella superclasse Dipendente e che perciò verrà ereditato dalle classi derivate, come ad esempio:
    public String riportaNome ()
    {
       return nome;
    }
    
    Questo metodo rende lecita l'struzione seguente per accedere al campo nome e riporta all'ambiente chiamante la stringa del valore del campo:
    imp.riportaNome()
    
  7. In generale non è possibile accedere direttamente al un campo privato di un istanza della superclasse, neppure tramite metodi definiti nella classe derivata, ma solo tramite metodi definiti nella classe base. Va notato però che la variabile privata della classe base esiste anche per gli oggetti della classe derivata, semplicemente non è accessibile direttamente.
  8. Inoltre non è possibile usare un metodo privato della superclasse, perchè non viene ereditato dalla classe derivata. Come dire che i metodi privati di una classe implementano funzionalità accessibili solo all'interno della classe, quindi possono essere invocati solo a partire da istanze di quella classe.

Si veda la classe Impiegato.java.

Esercizio 4

Risposte
Possibili soluzioni con i cicli for e while:
public static int[] init(int[] a)
{
   for (int i=0; i < MAX; i++)
      a[i]=2*i + 1;
   return a;
}
public static int[] init(int[] a)
{
   int i=0;
   while (i < MAX)
      a[i]=2*++i + 1;
   return a;
}

Si veda il programma Vettori.java con le due soluzioni implementate con metodi di classe.

Esercizio 5

Soluzione
public static int[] rimuovi(int p, int[] a) 
{
   for (int i = p; i < a.length-1;)
      a[i]=a[++i];
   a[a.length-1] = 0;	
   return a;
}
Si veda il programma Vettori.java.

Esercizio 6

Soluzione
public class Tokenizzatore 
{		  
   public static void  main (String[] a) 
   {
      System.out.print("input una riga di testo: ");                  
      String riga = Keyboard.readString();
      StringTokenizer processore_di_riga = new StringTokenizer(riga);                                 ;
      String [] frase = new String[processore_di_riga.countTokens()];                                          ;
        
      for (int i = 0; processore_di_riga.hasMoreTokens(); i++)
         frase[i] = processore_di_riga.nextToken();
      
      for (int i = 0; i < frase.length; i++)
	   System.out.println(frase[i]);
   }
}

Si veda la classe Tokenizzatore.java.

Esercizio 7

Soluzione
Numeri()
{
   array_numeri = new int[MAX];
   for (int i = 0; i < MAX; i++)
      array_numeri[i] = (int)(Math.random() * 10) + 1;
}
	
public int conta()
{
   int i = 0, cont = 0;
   while (i < MAX)
      if (array_numeri[i++]%2 == 0)
	   cont++;
   return cont;	
}

Si veda la classe Numeri.java.

Esercizio 8

Risposte

Sì è corretto. Perché il metodo elements() della classe Vector riporta un valore di tipo Enumeration, cioè riporta una enumerazione dei componenti del vettore. Il ciclo quindi costutisce la stampa delle componenti del vettore. Si noti che la classe Vector e l'interfaccia Enumeration si trovano entrambe nel pacchetto java.util

Esercizio 9

Soluzione
public boolean hasMoreElements() {
   if (indice == mazzo.length)
      return false;
   else 
      return true;
}
public Object nextElement() {
   return (Object)mazzo[indice++];
}

Si veda il programma EnumerationDemo.java.

Esercizio 10

Lo stack viene utilizzato da un metodo che scandisce l'espressione per valutarla, leggendo i diversi elementi d'informazione (token) ad uno ad uno: ad ogni token che può essere un operando viene effettuata una operazione di push sullo stack, mentre ad ogni token che rappresenta un simbolo di operazione vengono effettuate due operazioni di eliminazione dallo stack (pop) poi viene valutato il nuovo valore che viene successivamente inserito sullo stack (push).

1 5 + 2 * 3 1 + /
:

stack: 1
5 2 3 3 4
1 1 6 6 12 12 12 12 3
token:
1 5 + 2 * 3 1 + /

Si veda il programma Postfissa.java che adotta questa strategia mediante la struttura dati stack implementata con la classe Stack.

Esercizio 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10


M.A. Alberti, 12 luglio 2006