Dispense del corso di Linguaggi di programmazione e laboratorio Parte 1 di 2 Francesco Sisini Inverno 2014 Indice 1 La tecnologia Java 1.1 Le classi . . . . 1.2 Classi e oggetti . 1.3 Ereditarietà . . . 1.4 Polimorfisomo . 1.5 Organizzazione: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . namespace e packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 3 7 9 17 Convenzioni tipografiche Nel testo saranno utilizzate le convenzioni tipografiche di seguito elencate grassetto usato per evidenziare i nuovi termini man mano che verranno introdotti nel testo o i titoli dei paragrafi. inclinato usato per evidenziare le espressioni sulle quali si vuol porre lattenzione. monospaced usato per indicare linput/output del sistema (ci che digitato con la tastiera e che visualizzato sullo schermo dal sistema), i nomi ed il contenuto dei file, gli indirizzi di pagine web e quelli di posta elettronica. 1 Capitolo 1 La tecnologia Java 1.1 Le classi Esempio di base: editiamo il codice seguente: public class MyClass { public static void main(String args[]) { System.out.println("Hello World!"); } } e salviamolo con il nome di MyClass.java. Da un terminale editiamo: > javac MyClass.java poi > java MyClass Esempio di base: public class MyClass2 { public static void main(String args[]) { System.out.println("Hello World!"); if(args.length>0) System.out.println("Hello "+args[0]); } } Esempio di base: for-loop public class MyClass3 2 { public static void main(String args[]) { System.out.println("Hello World!"); for(int i=0;i<args.length;i++) System.out.println("Hello "+args[i]); } } Esempio di base: eccezzioni Verificare nella documentazione Oracle se la parola inglese exception debba essere tradotta come eccezione (quindi con una sola z) o eccezzione, seguendo il metodo Goldoni di traduzione tecnologico. Riportare la risposta con il mause in alto a destra. Poi riavviare la proceura senza fermarsi. public class MyClass_eccezione { public static void main(String args[]) { int i=1, j=2,k=0; try{ System.out.println(i/j); System.out.println(i/k); }catch(Exception e) { System.out.println("Eccezione: "+e.toString()); } } } Esercizio 1: si implementi una classe java che accetti in input un testo come argomento, verifichi la presenza di parole scurrili a partire da un database di parolaccie e produca in output il testo ripulito. 1.2 Classi e oggetti Directory: classesAndObjects Vediamo la classe Gatto. La proprietà di un gatto di essere felino è indipendente dalla sua specifica istanza, cosı̀ come il numero di code, di zampe e di denti del gatto inteso come specie animale non dipende dalla specifica istanza. 3 public class Gatto{ //attributi di classe public static String famiglia="felini"; public static int code=1; public static int zampe=4; public static String orecchie="morbide"; //Attributi di istanza public String nome; public String colore; //metodi di classe public static String riconosciRazza(String colore) { String razza="non nota"; if(colore.equalsIgnoreCase("grigio")) razza="Gattone comune."; if(colore.equalsIgnoreCase("rosso")) razza="Gattino speciale"; return razza; } //metodi istanza public void miagola() { System.out.println("Miaooooo!!!"); } public void faiLeFusa() { System.out.println("Frrrrr...Mrwwwww...Gruouoovv..."); } public Gatto(String ilnome, String ilcolore) { nome=ilnome; colore=ilcolore; } } public class MainGatto{ public static void main(String args[]) { //Accesso a attributi di classe System.out.println("Tutti i gatti sono "+Gatto.famiglia); 4 //Accesso a metodi di classe System.out.println("Il mio gatto grigio quindi "+Gatto.riconosciRazza("grigio")); un //Istanzio il mio gatto Gatto mioMiao=new Gatto("Fuffy","grigio"); System.out.println("Il mio gatto si chiama "+mioMiao.nome+" ed "+mioMiao.colore); System.out.println("Il mio gatto quando miagola fa..."); mioMiao.miagola(); System.out.println("Il mio gatto quando lo accarezzo fa..."); mioMiao.faiLeFusa(); } } Esercizio 2: provare a modifcare la classe MainGatto e ad accedere ai metodi e ai membri statici da una variabile di istanza e viceversa. Commentare i risultati della prova. Eseguiamo ora questa modifica alla classe gatto: public Gatto(String ilnome, String ilcolore) { nome=ilnome; colore=ilcolore; gattiIstanziati++; } e poi creiamo la classe GattiInJVM: public class GattiInJVM{ public static void main(String args[]) { //Istanzio il mio gatto Gatto gatto1=new Gatto("Pancieri","grigio"); Gatto gatto2=new Gatto("Matto","rosso"); System.out.println("Ci sono "+Gatto.gattiIstanziati+" gatti in questa JVM..."); Gatto gatto3=new Gatto("Consolato","rosso"); System.out.println("Ci sono "+Gatto.gattiIstanziati+" gatti in questa JVM..."); System.out.println("Ci sono: "+gatto1.nome+", "+gatto2.nome+" e "+gatto3.nome); } } 5 Esempio di base: classe statefull non eseguibile public class NonExecutableClass { public int counter; public String name; public void doIncrement() { counter++; } public int getCount() { return counter; } } Proviamo a compilare... e a eseguire la classe. Cosa succede? Questa classe non ha il metodo main. Proviamo ora a creare un instanza di questa classe e a invocarne i metodi: public class MainClass { public static void main(String args[]) { NonExecutableClass nex=new NonExecutableClass(); System.out.println("Conteggi iniziali"+nex.getCount()); nex.doIncrement(); System.out.println("Conteggi iniziali"+nex.getCount()); } } Ora proviamo l’approccio stateless: public class MainClassStateless { public static void main(String args[]) { NonExecutableClass nex=new NonExecutableClass(); System.out.println("Conteggi iniziali"+nex.doIncrement()); System.out.println("Conteggi iniziali"nex.doIncrement();); } 6 } public class NonExecutableClassStateless { public int doIncrement() { int counter=0; counter++; return counter; } } un approccio diverso:...con errore... public class MainClass2 { public NonExecutableClass nex; public static void main(String args[]) { nex=new NonExecutableClass(); System.out.println("Conteggi iniziali"+nex.getCount()); nex.doIncrement(); System.out.println("Conteggi iniziali"+nex.getCount()); } } compiliamo e...cosa succede? Cosa significa che non si può far riferimento ad una variabile non statica da un contesto statico? 1.3 Ereditarietà Directory: ereditarieta Facciamo qualche prova di ereditarietà. Partiamo da Aristotele che classifica l’essere umano come un vivente, animale, terresre e bipede. Vediamo alcune proprietà comuni agli elementi di questi insiemi. Senza pretesa di rigore possiamo affermare che ogni essere vivente si consuma, ogni animale si riproduce, ogni animale terrestre cammina e il bipede parla. Costruiami diverse classi che rappresentano questi insiemi: public class Vivente { public String consuma(String cibo){ //...consuma 7 return(cibo+" defecato!"); } } public class Animale extends Vivente { public Animale riproduciti(){ //...no comment return new Animale(); } } public class Terrestre extends Animale { int posizione; public void cammina(int metri) { posizione+=metri; } } public class Bipede extends Terrestre { public String nome; public void parla() { System.out.println("Bla...bla...bla."); } public Bipede(String ilnome) { nome=ilnome; } @Override public Bipede riproduciti(){ return new Bipede("..."); } } public class MainUmano { public static void main(String[] args){ //E fu creato l’uomo... Bipede uomo=new Bipede("Adamo"); 8 String c_cc_=uomo.consuma("spaghetti"); System.out.println("Se mangi spagetti..."+c_cc_); //E dalla sua costola...fi creata la donna Bipede donna=new Bipede("Eva"); System.out.println("Ciao io sono "+donna.nome); //Adamo raggiunge Eva che si trova 10 m piu’ in la’... uomo.cammina(10); System.out.println("Adamo si trova in posizione: "+uomo.posizione); //E senza aggiungere particolari fu creato un figlio... Bipede figlio= donna.riproduciti(); System.out.println("Ciao io sono "+figlio.nome); } } Esercizio 3: si implementi una classe rappresentante una automobile. Si segua l’esempio del Bipede in cui la classe è ottenuta per ereditarietà (per esempio l’automobile è un veicolo a motore con quattro ruote). 1.4 Polimorfisomo Directrory polimorfismo Vediamo come due istanze di classi diverse possono essere viste come istanze di una stessa classe. public class Partner { //Protected e private si chiamano modificatori di visibilit //attraverso di questi si tabiliscono le limitazioni all’accesso di campli e metodi (policy) //vedere le JLS (Java Language Specification) SE7, 6.6.1. Determining Accessibility. protected String nome; private String soprannome; public Partner(String ilnome) { nome=ilnome; soprannome="trottolino amoroso";//Riuscite ad acceder a questo campo da una classe derivata } 9 public String ripetimiIlTuoNome() { return nome; } public String pensaciTu(String problema) { return "...."; } } public class Cane extends Partner { private String codiceRegionale; public Cane(String nomeCane, String codReg) { //Devo sempre costruire anche la classe madre/padre super(nomeCane); codiceRegionale=codReg; } public String comunicamiEmozioniPiacevoli() { String pensiero="Tu sei il padrone/na della mia vita e ti amo alla follia, sposiamoci."; return pensiero+"->"+"Bau...uau...bau bau"; } } public class AmoreDellaVita extends Partner { public AmoreDellaVita(String nomeAmore) { super(nomeAmore); } public boolean sposiamoci() { return true; } public String comunicamiEmozioniPiacevoli() 10 { return "No, sono stanco/ca"; } } import java.util.*; public class MainConvivenza { Partner ilPartner; public static void main(String[] args) { if(args==null) { System.out.println("Con chi???"); System.exit(0); } if(args.length<2){ System.out.println("...indica il tipo di partner ed il nome"); System.exit(0); } //Questa volta facciamo sul serio, questo \‘e molto OO... MainConvivenza mc=new MainConvivenza(args[0],args[1]); } public MainConvivenza(String convivente, String nome) { if(convivente.equalsIgnoreCase("amoredellavita")) { ilPartner=new AmoreDellaVita(nome); } if(convivente.equalsIgnoreCase("cane")) { ilPartner=new Cane(nome,"123");//Tagliamo corto } double ps=probabilitaSuccesso(ilPartner); System.out.println("Probabilit di successo: "+ps); } private double probabilitaSuccesso(Partner pr ) { //Questa pratica non bella...anzi sconsigliata: //http://stackoverflow.com/questions/541749/how-to-determine-an-objects-class-in-java String className=pr.getClass().getName(); 11 double prob=Math.random(); if(prob<0.5) System.out.println("il "+className+" non partner ideale..."); return prob; il tuo } } Esercizio 4: Licia è amica di Andrea che ha un fratello di nome Mirko, cantante di una nota band giovanile e molto apprezzato dai coetanei. Andrea ha un animale domestico che mangia la colazione offerta dal papà di Licia, di solito sono polpette ma potrebbe anche essere altro. Si implementi una struttura di classi che permetta di rappresentare questa realtà e che permetta ad Andrea di avere un gatto o un cane che produca il verso adeguato e che possa alimentarsi con i piatti del papà di Licia. Possibile implementazione //Vedere JLS SE7, 8.1.1.1. abstract Classes public abstract class Cibo { } public abstract class AnimaleDomestico { public String nome; public AnimaleDomestico(String ilnome) { nome=ilnome; } public abstract void svarsela(); public void mangia(Cibo cib) { System.out.println("Buono il..."+cib.getClass().getName()); } } public class Cane extends AnimaleDomestico { public Cane(String ilnome){ super(ilnome); } public void svarsela() 12 { System.out.println("Bauuuu...."); } } public class Gatto extends AnimaleDomestico { public Gatto(String ilnome){ super(ilnome); } public void svarsela() { System.out.println("Miaaaoo...."); } } public class Persona { // Consulatare http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html public static enum Sesso {MASCHIO,FEMMINA}; public static enum TipoRapporto {AMICO,FRATELLO,PADRE,FIGLIO} public String nome; public String cognome; public Sesso ilsesso; public Persona amico, fratello,padre,figlio; public AnimaleDomestico animaletto; public Persona(String n, String c, Sesso poco) { nome=n; cognome=c; ilsesso=poco; } public void aggiungiRapporto(Persona pr, TipoRapporto tp) { //Consultare http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html switch (tp) { case AMICO: amico=pr; 13 break; case FRATELLO: fratello=pr; break; case PADRE: padre=pr; break; case FIGLIO: figlio=pr; } } public void nutri(AnimaleDomestico pet) { pet.mangia(new Polpette("uova, maiale e fagioli")); } } public class Polpette extends Cibo { public String ingredienti; public Polpette(String listaIngredienti) { ingredienti=listaIngredienti; } } public class MainKissMeLicia { public static void main(String[] args){ MainKissMeLicia kml=new MainKissMeLicia(); } public MainKissMeLicia() { Persona mirko=new Persona("Mrko","Kato",Persona.Sesso.MASCHIO); Persona licia=new Persona("Licia","Mitamura",Persona.Sesso.FEMMINA); Persona andrea=new Persona("Andrea","Kato",Persona.Sesso.MASCHIO); Persona marrabbio=new Persona("Marrabio","Mitamura",Persona.Sesso.MASCHIO); Gatto giuliano=new Gatto("Giuliano"); mirko.aggiungiRapporto(andrea,Persona.TipoRapporto.FRATELLO); andrea.aggiungiRapporto(mirko,Persona.TipoRapporto.FRATELLO); andrea.aggiungiRapporto(licia,Persona.TipoRapporto.AMICO); marrabbio.aggiungiRapporto(licia,Persona.TipoRapporto.FIGLIO); 14 mirko.aggiungiRapporto(licia,Persona.TipoRapporto.AMICO); System.out.println("****KISS ME LICIA****"); System.out.println("Il fratello di mirko :"+mirko.fratello.nome); System.out.println("Il fratello di andrea :"+andrea.fratello.nome); System.out.println("L’amica di Andrea p:"+andrea.amico.nome); System.out.println("La figlia di Marrabbio :"+marrabbio.figlio.nome); System.out.println("L’amica...di Mirko :"+mirko.amico.nome); marrabbio.nutri(giuliano); } } Esercizio 5: Si prenda visione del tips: http://stackoverflow.com/questions/541749/how-to-determine-an-objects-class-in-java e lo si commenti. Esercizio 6: Si commenti l’uso della memoria da parte della JVM durante l’esecuzione di MainKissMeLicia. Directory: interfaccia public interface USB { //Vedi JLS se7, 8.9. Enums public enum Dispositivi{MAUSE, TASTIERA, SMARTPHONE, SSD, STAMPANTE, FOTOCAMERA}; public enum TipoUSB{TIPO_A, TIPO_B,MINI_TIPO_A,MINI_TIPO_B,MICRO_TIPO_A,MICRO_TIPO_B}; public byte readNext(); public boolean writeByte(byte b); } public interface Display { public void displayPixelAt(int x, int y); public void printCharAt(int x, int y, char c); } public interface Tastiera 15 { public void pressKey(byte key); public void pressKey(byte key1,byte key2); public void pressKey(byte key1, byte key2, byte key3); } import java.util.*; public final class ComputerDevice implements USB, Tastiera, Display { public final String modello; public ComputerDevice(String ilmodello) { modello=ilmodello; } //Ora dobbiamo implementare tutti i metodi dichiarati nelle interfaccie //USB public byte readNext() { int r=(int)(Math.random()*255); byte b=(byte)r; return b; } public boolean writeByte(byte b) { return true; } //Tastiera public void pressKey(byte key) { } public void pressKey(byte key1,byte key2){ } public void pressKey(byte key1, byte key2, byte key3){ } //Display public void displayPixelAt(int x, int y) { } public void printCharAt(int x, int y, char c) { } 16 } public class MainUtente { private USB myUSB; private Tastiera myTastiera; private Display myDisplay; public MainUtente(String ilmodello) { ComputerDevice cd=new ComputerDevice(ilmodello); myUSB=(USB)cd; myTastiera=(Tastiera)cd; myDisplay=(Display)cd; } public void goditiIlComputer() { myUSB.readNext(); myDisplay.displayPixelAt(1,1); myTastiera.pressKey((byte)1); } public static void main(String[] args) { MainUtente mu=new MainUtente("Un modello..."); mu.goditiIlComputer(); } } Esercizio 7: Si presentino i concetti principali legati alla programmazione ad oggetti ed al polimorfismo. In particolare si esponga la loro implementazione nella tecnologia Java. Si faccia ampio uso della documentazione ufficiale e si riporti sempre il riferimento alla fonte specificando il nome del documento, il numero del capitolo, paragrafo ecc. 1.5 Organizzazione: namespace e packages Directory: namespece Creare la dir dirremota e li editare il file ClasseSociale.java public class ClasseSociale { public static String classe="Standard"; } 17 Compilare ClasseSociale.java. Poi tornando nella dir namespace compilare MainSociale.java. public class MainSociale { public static void main(string[] args) { ClasseSociale cs=new Classe Sociale(); } } Provando a compilare MainSociale.java si ha un errore in quanto il compilatore non trova la classe ClasseSociale.class. Proviamo ora a compilare specificando il classpath javac -cp ./:./dirremota MainSociale.java, la compilazione va a buon fine. (Per chi usa Windows adeguare la grmmatica del path). Creiamo ora la directory ./namespace/unife/linguaggi/utilita/ e li editiamo la class GrattaSchiena.java: package unife.linguaggi.utilita; public class GrattaSchiena { protected void gratta() { System.out.println("Gratta...gratta!"); } } Nella directory namespace editaimo la classe MainGratta.java: public class MainGratta { private unife.linguaggi.utilita.GrattaSchiena gs; public MainGratta() { } public static void main(String[] args) { 18 MainGratta mg=new MainGratta(); mg.gs=new unife.linguaggi.utilita.GrattaSchiena(); } } Compilare ed eseguire la classe MainGratta. Poi agiungiamo la chiamata al metodo gratta(): public static void main(String[] args) { MainGratta mg=new MainGratta(); mg.gs=new unife.linguaggi.utilita.GrattaSchiena(); mg.gs.gratta(); } Compilare il codice. Qual’è il risultato della compilazione? Esercizio 8: Si consulti la documentazione normativa della Oracle riguardo JLS se7 per il modificatore di visibilità protected. Si corregga quindi il codice precedente affinch compili correttamente e si illustri il problema a la risoluzione ricordando di citare correttamente la fonte ufficiale. 19