Programmazione per TWM: Esercitazione di laboratorio #19 (06/05)

Gli obiettivi di questa esercitazione sono: capire e saper utilizzare interfacce e classi astratte (capitolo 10 fino a 10.3).

Raccomandazioni: Ove non altrimenti indicato, rispondete alle domande prima ragionando su carta e poi provando a editare, compilare ed eseguire. Gli esercizi etichettati con l'asterisco (*) sono più difficili: affrontateli dopo aver risolto gli altri.

Esercizio 1

Obiettivo: saper utilizzare classi astratte ed eredità.

Attività:

  1. Completate le seguenti classi (non è detto che tutti i puntini vadano riempiti), per fare in modo che il programma Esercizio1 stampi 77,33:
    ... class A ... {
      ... int m2() {return 3;}
      ... int m3() {return 1;}
    }
    ... class B ... {
      ... int m3() {return 5;}
    }
    ... class C ... {
      ... int m1() {return 11;}
    }
    
    ... class D ... {
      ... int m2() {return 7;}
      ... int m3();
    }
    class Esercizio1 {
      public static void main(String[] args) {
        D pluto = new ...;
        ... pippo = new ...;
        System.out.println((pippo.m2()*pippo.m1()) + "," 
        + (pluto.m1()*pluto.m2()*pluto.m3()));
      }
    }
    Esistono più soluzioni? Se sì, quale è la "migliore"? Perché?
  2. Scrivere la classe SegmentoOrizzontale che estende la classe DisegnabileConCarattere e che rappresenta un segmento di lunghezza fissata.
    Gli oggetti della classe DisegnabileConCarattere vengono "disegnati" su schermo usando caratteri, e il carattere usato viene memorizzato in un attributo c.
    abstract class DisegnabileConCarattere {
      protected char c = '*';
      public void impostaCarattere(char c) {
        this.c = c;
      }
      protected char carattere() {
        return this.c;
      }
      abstract String disegna();
    }
    Il metodo disegna() non deve disegnare a schermo, ma restituire una rappresentazione sotto forma di stringa.
    La classe SegmentoOrizzontale deve avere un costruttore in cui si passa come parametro la lunghezza. Il metodo toString() deve essere il seguente:
    public String toString() {
      return disegna();
     }
  3. Scrivere il programma UsaSegmentoOrizzontale che crea un segmento lungo 6 e lo stampa a schermo 3 volte con 3 caratteri diversi ottenendo il seguente output:
    > java UsaSegmentoOrizzontale
    ******
    ######
    ------
    
    Dovete usare solo i metodi dell'oggetto segmento, ereditati e non.
  4. (*) Definire la classe SegmentoVerticale analoga a SegmentoOrizzontale. Anche in questo caso il metodo toString() deve contenere la sola istruzione return disegna();. Per evitare questa duplicazione di codice, in quale classe sarebbe stato meglio definire il metodo toString()? Verificate la vostra risposta modificando il codice, ricompilando ed eseguendo di nuovo UsaSegmentoOrizzontale.

Esercizio 2

Obiettivo: comprendere l'uso delle interfacce.

Attività:

  1. Completate il codice seguente (non è detto che tutti i puntini vadano sostituiti) per far in modo che il programma Esercizio2 stampi prima 15 e poi 7.
    interface A {
      public int m1();
    }
    
    ... B {
      public int m2();
    }
    interface C extends ... {
    }
    
    class D extends ... implements ... {
      public int m1() {return 7;}
    }
    class E implements C {
      public int m1() {return 3;}
      public int m2() {return 5;}
    }
    class F {
      public int m3() {return 1;}
    }
    class Esercizio2 {
      public static void main(String[] args) {
        C pippo = new ...;
        ... pluto = new D();
        prova1(pippo);
        prova2(pluto);
      }
      public static void prova1(... x) {
        System.out.println(x.m1()*x.m2());
      }
      public static void prova2(... x) {
        System.out.println(x.m1()*x.m3());
      }
    }
    Esiste un'unica soluzione? Verificate tutte le soluzioni che vi sembrano corrette ricompilando ed eseguendo nuovamente il programma. Ne esiste una "migliore"? Se sì, perché la ritenete tale?
  2. Considerate il codice dell'attività precedente. Completate il seguente per far stampare 143 al programma Esercizio2 modificato qui di seguito.
    ... G implements A, B {
      public int m1() {return 11;}
    }
    class H ... {
      public int m2() {return 13;}
    }
    class Esercizio2 {
      public static void main(String[] args) {
        ... pippo = new ...;
        System.out.println(pippo.m1()*pippo.m2());
      }
    }
  3. Definire l'interfaccia Riproducibile che rappresenta le "cose" che possono essere riprodotte sui registratori, lettori di dischi ottici e simili. I metodi dell'interfaccia devo essere quelli che permettono di
  4. Definire l'interfaccia Registrabile con i metodi per iniziare e terminare la registrazione.
    Definire le classi Video e Audio che implementano le interfacce Riproducibile e Registrabile con metodi che consistono della sola istruzione
    System.out.println("Sono nel metodo ... della classe ...");
    
    (sostituite i puntini con il nome del metodo).
  5. Completare il programma Esercizio3 in modo che
    class Esercizio3 {
      public static void main(String[] args) {
        ... unVideo = ...;
        prova(unVideo);
        ... unAudio = ...;
        prova(unAudio);
      }
      ...
    }
    Suggerimento: quanti metodi statici prova dovete scrivere?
  6. (*) Come si può modificare la gerarchia dell'attività precedente per evitare duplicazione di codice?

Valid HTML 4.01! Valid CSS! Paolo Coppola
Last modified: 2003-05-06