La Piattaforma Java

Mappa

TOPIC

Introduzione

Il nome piattaforma \xE8 giustificato dal fatto che con Java non si pu\xF2 intendere solo il linguaggio ma quasto va integrato con la Java Virtual Machine che \xE8 appunto una macchina virtuale ( vedi Tannenbaum ) per la quale viene compilato il linguaggio. Una breve ed efficace presentazione dell'architettura del linguaggio Java \xE8 disponibile QUI

L'Architettura

Gli strati che compongono la tecnologia Java sono sintetizzati nella figura a Fianco. L'aspetto peculiare \xE8 il fatto che Java \xE8 una *piattaforma completamente software* helloWorld.gif

Piattaforma Java

la Piattaforma Java ha due componenti essenziali:
  • La Java Virtual Machine (macchina Virtuale Java)
  • La API Java (Java Application Program Interface)
getStarted-jvm.gif

Java Launcher Tool

E' il Java launcher tool che insieme all'applicazione Java si occupa di lanciare anche la Java Virtual Machine

il Linguaggio

Il sito Oracle mette a disposizione un Wite Paper con una efficace intriduzione al linguaggio.

La Convenzione del Nome dei File Sorgente di Java

Usualmente il codice sorgente dovrebbe essere salvato in un file il cui nome si basa sul nome della classe. Per esempio il seguente codice definendo la classe pippo
import java.awt.*;

public class pippo extends Component 
{
    // .....
}

dovrebbe essere salvato nel file pippo.java

Variabili

I nomi di variabile riconoscono maiuscole e minuscole e non possono iniziare con un numero .

Tipi di dati primitivi

Integere Numeric    
  byte 8-bit
  short 16-bit
  int 32-bit
  long 64-bit

Real Numeric    
  float 32-bit
  double 64-bit

Character Data type    
  char 16-bit Unicode character
    char myChar 'Testo' ;

Boolean Data type    
  boolean true or false

Array

Le tabelle sono degli oggetti che hanno una rappresentazione a livello di run-time quindi vengono gestiti a livello di macchina virtuale.

Un array viene diachiarato con una sintassi simile al C
float myFloat[];

La precedente sintassi,bench\xE8 corretta \xE8 deprecata. . La dichiarazione dell'array non alloca la memoria ma definisce solo la tipologia dell'array.
float[] myFloat;
byte[] anArrayOfBytes;
short[] anArrayOfShorts;
long[] anArrayOfLongs;

L'allocazione reale di memoria viene fatta con l'utilizzo dell'operatore new

// create an array of integers
anArray = new int[10];

La sua inizializzazione pu\xF2 essere fatta contestualmente alla allocazione con la seguente sintassi dove vengono usate le { }

int[] anArray = { 
    100, 200, 300,
    400, 500, 600, 
    700, 800, 900, 1000
};

Per accedere agli elementi di un array si usa la sintassi classica del C/C++

float myFloat[];   
int  i;
for (i = 0;  i < 10;  i++) {
          myPoints[i] = new Point();                
                 }

Il dimensionamento \xE8 dinamico, l'istanza myFloat.length restituisce il numero di elementi dell'0array

String

Il tipo "String" \xE8 a tutti gli effetti un oggetto. Esistono due tipi di "oggetti string" uno immutabile, costante String ed uno modificabile StringBuffer. L'assegnazione anzich\xE8 seguire la sintassi tipica dell'istansazione diun oggetto segue quella tipicadel linguaggio C

String hello = "Hello world!";

System.out.println("There are " + num + " characters in the file.");

Ilsimbolo + puo essere usato per la concatenazione di pi\xF9 variabili string in un'unica variabile.

Stampa Formattata di Testo e Numeri

Per una completa comprensione e' preferibile affrontare questa sezione dopo aver visto i concetti di oggetto e metodo. La sezione si trova Qui

Operatori

Tabella completa QUI
Operators Precedence
postfix
expr++ expr--
unary
=++expr --expr +expr -expr ~ !=
multiplicative
* / %
additive
+ - 
shift
<< >> >>> 
relational
< > <= >= instanceof 
equality
== !=
bitwise AND
   &
bitwise exclusive OR
   ^
bitwise inclusive OR
 | 
logical AND
&&
logical OR
|| 
ternary
   ? : 
assignment
   = += -= *= /= %= &= ^= |= <<= >>= >>>=| 

Operatori di Ordine

==      equal to
!=      not equal to
>       greater than
>=      greater than or equal to
<       less than
<=      less than or equal to

Operatori Logici

&& Conditional-AND
|| Conditional-OR

L'operatore instanceof controlla l'appartenenza di un oggetto ad una determinata classe

class InstanceofDemo {
    public static void main(String[] args) {
        Parent obj1 = new Parent();
        Parent obj2 = new Child();
        System.out.println("obj1 instanceof Parent: "
            + (obj1 instanceof Parent));
        System.out.println("obj1 instanceof Child: "
            + (obj1 instanceof Child));
           .....
    }
}

Istruzioni per il Controllo di Flusso

if then e if then else

L' if- then \xE8 il pi\xF9 fondamentale di tutte le istruzioni di controllo . Dice al tuo programma di eseguire una determinata sezione di codice solo se "express" restituisce true (vero). Ad esempio, la classe Bicicletta potrebbe consentire i freni per diminuire la velocit\xE0 della bicicletta solo se la bicicletta \xE8 gi\xE0 in movimento . Una possibile implementazione del metodo applyBrakes potrebbe essere il seguente :

void applyBrakes() {
    // the "if" clause: bicycle must be moving
    if (isMoving){ 
    // isMoving=express
        // the "then" clause: decrease current speed
        currentSpeed--;
    }
}

Se questo test restituisce false (ovvero la bicicletta non \xE8 in movimento ) , il controllo passa alla fine della dichiarazione if-then .

Inoltre , le parentesi di apertura e chiusura sono opzionali , a condizione che il " poi " clausola contiene una sola istruzione :

void applyBrakes() {
    // same as above, but without braces 
    if (isMoving)
        currentSpeed--;
}

L'istruzione switch

The switch Statement

A differenza di if-then e if-then-else, l'istruzione switch pu\xF2 avere un numero di possibili percorsi di esecuzione. Un interruttore funziona con il byte, short, char, e tipi di dati primitivi int. Funziona anche con tipi enumerati, la classe String, e alcune classi speciali che avvolgono alcuni tipi di dati primitivi: Carattere, byte, short, e Integer (discusso in numeri e stringhe).

Il seguente esempio di codice, SwitchDemo, dichiara un int mese denominato il cui valore rappresenta un mese. Il codice visualizza il nome del mese, in base al valore del mese, utilizzando switch.


public class SwitchDemo {
    public static void main(String[] args) {

        int month = 8;
        String monthString;
        switch (month) {
            case 1:  monthString = "January";
                     break;
            case 2:  monthString = "February";
                     break;
            case 3:  monthString = "March";
                     break;
            case 4:  monthString = "April";
                     break;
            case 5:  monthString = "May";
                     break;
            case 6:  monthString = "June";
                     break;
            case 7:  monthString = "July";
                     break;
            case 8:  monthString = "August";
                     break;
            case 9:  monthString = "September";
                     break;
            case 10: monthString = "October";
                     break;
            case 11: monthString = "November";
                     break;
            case 12: monthString = "December";
                     break;
            default: monthString = "Invalid month";
                     break;
        }
        System.out.println(monthString);
    }
}
In questo caso, Agosto viene stampato sullo standard output.

Il corpo di un'istruzione switch \xE8 noto come un blocco di commutazione. Una dichiarazione nel blocco switch pu\xF2 essere etichettato con una o pi\xF9 etichette predefinite. L'istruzione switch valuta la sua espressione, quindi esegue tutte le istruzioni che seguono l'etichetta di corrispondenza.

.

L'Istruzione while e do-while

L'istruzione while esegue continuamente statement(s) mentre una particolare espressione expr \xE8 vera. La sua sintassi pu\xF2 essere espresso come:

while (expr) {
     statement(s)
}

L' istruzione while valuta l'espressione expr, che deve restituire un valore booleano. Se l'espressione expr restituisce true, l'istruzione while esegue statement(s) nel blocco while. L' istruzione while continua a testare l'espressione expr e l'esecuzione di suo blocco fino a quando l'espressione expr restituisce false. Utilizzando l'istruzione while per stampare i valori da 1 a 10 pu\xF2 essere realizzato come nel seguente programma WhileDemo:

class WhileDemo {
    public static void main(String[] args){
        int count = 1;
        while (count < 11) {
            System.out.println("Count is: " + count);
            count++;
        }
    }
}

\xC8 possibile implementare un loop infinito utilizzando l' istruzione while come segue:

while (true){
    // your code goes here
}

Il linguaggio Java fornisce anche un comando do - while, che pu\xF2 essere espresso come segue:

do {
     statement(s)
} while (expression);

La differenza tra do- while e while \xE8 che do- while ha la sua espressione expr nella parte inferiore del ciclo anzich\xE9 in alto. Pertanto, le statement(s) all'interno del blocco do vengono sempre eseguiti almeno una volta, come mostrato nella seguente programma DoWhileDemo :

class DoWhileDemo {
    public static void main(String[] args){
        int count = 1;
        do {
            System.out.println("Count is: " + count);
            count++;
        } while (count < 11);
    }
}

L'Istruzione for

L'istruzione for fornisce un modo compatto per iterare su un intervallo di valori. I programmatori spesso si riferiscono ad esso come il "for loop", perch\xE8 essa si ripete un numero di volte pari ad il numero di valori nell'intervllo.
L' istruzione for pu\xF2 essere espressa come segue:
 for (initialization; termination;
     increment) {
    statement(s)
} 
  • initialization inizializza il ciclo;
  • quando termination \xE8 falsa, il ciclo termina;
  • increment viene richiamato dopo ogni iterazione del ciclo, serve ad incrementare o decrementare un valore;

Il seguente programma \xE8 un esempio di come utilizzare la forma generale dell'istruzione for; nell'esempio, l'istruzione for viene usata per stampare i numeri da 1 a 10:
class ForDemo {
    public static void main(String[] args){
         for(int i=1; i<11; i++){
              System.out.println("Count is: " + i);
         }
    }
}

Notate come il codice dichiara una variabile all'interno dell'espressione di inizializzazione. L'ambito (l'ambito di un identificatore \xE8 la regione del programma, all'interno del quale rappresenta una certa cosa) di questa variabile si estende dalla sua dichiarazione alla fine del blocco disciplinato dall'istruzione for, in modo che possa essere utilizzato nell' espressioni di terminazione e d' incremento. Se la variabile che controlla l'istruzione for non \xE8 necessaria al di fuori del ciclo, \xE8 meglio dichiarare la variabile nell'espressione di inizializzazione. Le tre espressioni del ciclo for (initialization, termination, increment) sono opzionali; un ciclo infinito pu\xF2 essere creato come segue:
// infinite loop
for ( ; ; ) {
    
    // your code goes here
}

L'istruzione for ha anche un'altra forma progettata per l'iterazione attraverso Collections e array. Questa forma pu\xF2 essere utilizzata per rendere i loop pi\xF9 compatti e di facile lettura.
class EnhancedForDemo {
    public static void main(String[] args){
         int[] numbers = 
             {1,2,3,4,5,6,7,8,9,10};
         for (int item : numbers) {
             System.out.println("Count is: " + item);
         }
    }
}

Le Istruzione break, continue e return

L'istruzione break

L'istruzione break ha due forme: con etichetta e senza etichetta. Hai visto la forma non marcata nella discussione precedente dell'istruzione switch. \xC8 inoltre possibile utilizzare una pausa senza etichetta per terminare un for, while, o do-while, come mostrato nella seguente programma BreakDemo:
 
class BreakDemo {
    public static void main(String[] args) {

        int[] arrayOfInts = 
            { 32, 87, 3, 589,
              12, 1076, 2000,
              8, 622, 127 };
        int searchfor = 12;

        int i;
        boolean foundIt = false;

        for (i = 0; i < arrayOfInts.length; i++) {
            if (arrayOfInts[i] == searchfor) {
                foundIt = true;
                *break*;
            }
        }

        if (foundIt) {
            System.out.println("Found " + searchfor + " at index " + i);
        } else {
            System.out.println(searchfor + " not in the array");
        }
    }
}
Questo programma cerca il numero 12 in un array. L'istruzione break, indicato in grassetto, termina il ciclo for quando viene rilevato tale valore. Controllo di flusso poi il trasferimento alla dichiarazione dopo il ciclo for. L'istruzione break termina l'istruzione etichettata; non trasferisce il flusso di controllo per l'etichetta. Il flusso di controllo viene trasferito all'istruzione immediatamente dopo il "terminato".

L'istruzione continue

L'istruzione continue salta l'iterazione di un for, while, o do-while. La forma non marcata salta alla fine del corpo del ciclo pi\xF9 interno e valuta l'espressione booleana che controlla il ciclo. Il programma seguente, ContinueDemo, passa attraverso una stringa, contando le occorrenze della lettera "p". Se il carattere corrente non \xE8 una p, l'istruzione continue salta il resto del ciclo e procede al carattere successivo. Se invece \xE8 una "p", il programma incrementa il conteggio della lettera:
 
class ContinueDemo {
    public static void main(String[] args) {

        String searchMe = "peter piper picked a " + "peck of pickled peppers";
        int max = searchMe.length();
        int numPs = 0;

        for (int i = 0; i < max; i++) {
            // interested only in p's
            if (searchMe.charAt(i) != 'p')
                *continue*;

            // process p's
            numPs++;
        }
        System.out.println("Found " + numPs + " p's in the string.");
    }
}
Per vedere questo effetto in modo pi\xF9 chiaro basta rimuovere l'istruzione continue e ricompilarlo. Quando si esegue nuovamente il programma, il conteggio sar\xE0 sbagliato.

L'istruzione return

L'ultima delle dichiarazioni di ramificazione \xE8 l'istruzione return. L'istruzione return esce dal metodo corrente, e il flusso di controllo ritorna al punto in cui \xE8 stato richiamato il metodo. L'istruzione return ha due forme: una che restituisce un valore, e uno che non lo fa. Per restituire un valore, \xE8 sufficiente mettere il valore (o un'espressione che calcola il valore), dopo la parola chiave return ritorno ++ contare; Il tipo di dati del valore restituito deve corrispondere al tipo di valore di ritorno del metodo dichiarato. Quando un metodo viene dichiarato nullo, usa il modulo di ritorno che non restituisce un valore ritorno.

Operatori Logici

Gli Operatori di relazione e di uguaglianza determinano se un operando \xE8 maggiore, minore, uguale o non uguale ad un altro operando. La maggior parte di questi operatori vi potr\xE0 risultare familiare. Tenete a mente che si deve usare "==", non "=", durante la prova se due valori primitivi sono uguali.

==      equal to
!=      not equal to
>       greater than
>=      greater than or equal to
<       less than
<=      less than or equal to

Il programma seguente, ComparisonDemo, verifica gli operatori di confronto:

class ComparisonDemo {
public static void main(String[] args){
        int value1 = 1;
        int value2 = 2;
        if(value1 == value2)
            System.out.println("value1 == value2");
        if(value1 != value2)
            System.out.println("value1 != value2");
        if(value1 > value2)
            System.out.println("value1 > value2");
        if(value1 < value2)
            System.out.println("value1 < value2");
        if(value1 <= value2)
            System.out.println("value1 <= value2");
    }
} 

Operatori Condizionali

Il && e || sono operatori che eseguono Conditional-AND and Conditional-OR e operazioni condizionali o su due variabili booleane. Questi operatori presentano un comportamento detto a "corto-circuito", ci\xF2 significa che il secondo operando viene valutato solo se necessario.

&& Conditional-AND || Conditional-OR

Il programma seguente, ConditionalDemo1, testa questi operatori:

 

   class ConditionalDemo1 {

    public static void main(String[] args){
        int value1 = 1;
        int value2 = 2;
        if((value1 == 1) && (value2 == 2))
            System.out.println("value1 is 1 AND value2 is 2");
        if((value1 == 1) || (value2 == 1))
            System.out.println("value1 is 1 OR value2 is 1");
    }
}

Un altro operatore condizionale \xE8:?, Che pu\xF2 essere pensato come abbreviazione di un if-then-else (discussa nella sezione Controllo flusso dichiarazioni di questa lezione). Questo operatore \xE8 anche conosciuto come l'operatore ternario perch\xE9 utilizza tre operandi. Nel seguente esempio, questo operatore deve essere letto come: "Se someCondition \xE8 vero, si deve assegnare il valore di valore1, altrimenti assegnare il valore di valore2 al risultato.\xBB.

Il programma seguente, ConditionalDemo2, verifica l': operatore?:


class ConditionalDemo2 {

    public static void main(String[] args){
        int value1 = 1;
        int value2 = 2;
        int result;
        boolean someCondition = true;
        result = someCondition ? value1 : value2;

        System.out.println(result);
    }
}

Perch\xE9 someCondition \xE8 vero, questo programma stampa "1" nella schermata. Conviene utilizzare l'operatore invece di un'istruzione if-then-else se ci\xF2 rende il codice pi\xF9 leggibile;? per esempio, quando le espressioni sono senza effetti collaterali e compatte (quali assegnazioni).

Il tipo Instance Of (Operatore di confronto)

L'operatore instanceof paragona un oggetto a un tipo specificato. Si pu\xF2 usare per verificare se un oggetto \xE8 un'istanza di una classe, un'istanza di una sottoclasse, o un'istanza di una classe che implementa una particolare interfaccia.

Il programma seguente, InstanceofDemo, definisce una classe genitore (denominata Parent), una semplice interfaccia (denominata MyInterface), e una classe figlia (denominata Bambino) che eredita dal genitore e implementa l'interfaccia.

 class InstanceofDemo {
    public static void main(String[] args) {

        Parent obj1 = new Parent();
        Parent obj2 = new Child();

        System.out.println("obj1 instanceof Parent: "
            + (obj1 instanceof Parent));
        System.out.println("obj1 instanceof Child: "
            + (obj1 instanceof Child));
        System.out.println("obj1 instanceof MyInterface: "
            + (obj1 instanceof MyInterface));
        System.out.println("obj2 instanceof Parent: "
            + (obj2 instanceof Parent));
        System.out.println("obj2 instanceof Child: "
            + (obj2 instanceof Child));
        System.out.println("obj2 instanceof MyInterface: "
            + (obj2 instanceof MyInterface));
    }
}

class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}

Quando si utilizza l'operatore instanceof, bisogna tenere a mente che nulla non \xE8 un'istanza di nulla.

Linguaggio Orientato agli Oggetti

Gli aspetti principali sono:

  1. Encapsulation--implements information hiding and modularity (abstraction)
  2. Polymorphism--the same message sent to different objects results in behavior that's dependent on the nature of the object receiving the message
  3. Inheritance--you define new classes and behavior based on existing classes to obtain code re-use and code organization
  4. Dynamic binding--objects could come from anywhere, possibly across the network. You need to be able to send messages to objects without having to know their specific type at the time you write your code. Dynamic binding provides maximum flexibility while a program is executing

Ogni oggetto \xE8 definito dalle sue

  • Instance variables sono i dati incapsulati all'interno dell'oggetto che ne definiscono il comportamento
  • metodi codice che agendo sui dati modifica lo stato delll'oggetto

Classi

Una classe \xE8 il particolare inieme di codice che viene richiamato durante la definizione di un oggetto da parte dul modulo applicativo del programma. La classe \xE8 costituita da:

  • Campi (Field) cio\xE8 dati
  • metodi cio\xE8 istruzioni che operano sui campi

Ecco un esempio

    class Point extends Object {
                 public double  x;    /*  instance variable  */
                public double  y;    /*   instance variable  */
                  }

Tipi dei Membri delle Classi ( Variabile di Stato, "Istance Variables" e Metodi )

Le variabili di "stato" possono assumere 4 diversi protocolli per ci\xF2 che concerne la loro interazione con i processi esterni alla classe
  1. private I membri definiti in questo modo sono accessibili solo dall' interno del codice della classe stessa; la loro manipolazione pu\xF2 avvenire solo attraverso il " passaggio di messaggi " con codice esterno.
  2. public I membri cos\xEC definiti sono accessibili a chiunque
  3. protected i menbri cos\xEC definiti sono acccessibili solo alle loro sottoclassi (subclass)
  4. "non dichiarato" i menbri che non vengono dichiarati sono assunti amichevoli (frinedly) e sono acccessibili dalle classi dello stesso package

I valori assunti da queste variabili sono diversi per ogni oggetto appartenente alla classe

Istanziazione di una Classe

Si intende la definizione di un oggetto (variabile) appartenente all'insieme definito dalla classe (la classe infatti definisce la propriet\xE0 caratteristica dell'insieme )

    Point  myPoint;          //               declares a variable to refer to a Point  object
    myPoint = new Point();   //   allocates an instance of  a Point  object

La keyword new definisce l'inizializzazione dell'oggetto. Il riferimento all'istanza usa la sintassi classica del C

             myPoint.x = 10.0;
              myPoint.y = 25.7;

Static Variable

le variabili statiche assumono valori associati alla classe anzich\xE8 all'oggetto generato (istanziato) per questo vengono precedute alla keyword static

Constructor

I "Constructor" sono metodi, con lo stesso nome della classe, che vengono chiamati nel momento in cui si "istanzia" un oggetto della classe. Inizializzano le istanze dell'oggetto oppure assegnano dei valori definiti successivamente all'istanzazione dell'oggetto. L'esempio precedente viene ad essere cos\xEC modificato:

    class Point extends Object {
        public double  x;    /*   instance variable  */
       public double  y;    /*   instance variable  */
       Point() {        /*  constructor to initialize to default zero value  */
            x = 0.0;
            y = 0.0;
        }
  /*   constructor to initialize to specific value 
Point(double x, double y) {
            this.x = x;    /*  set instance variables to passed parameters  */
            this.y = y;
        }
    }

la variabile this

All'interno del codice di una classe per riferirsi affermare che ci si sta riferendo alle istanze della stessa classe si pu\xF2 usare l'istanza this come si \xE8 fatto nell'esempio precedente:
Point(double x, double y) {
            this.x = x;    /*  set instance variables to passed parameters  */
            this.y = y;
        }
    }

Sotto-Classi

Le Classi posso essere estese (extended) attraverso le Sotto Classi Il codice che definisce la sotto-classe arricchisce la classificazione, dovendo fornire la propriet\xE0 caratteristica del sottoinsieme della classe originaria. La sottoclasse in termini di relazioni fornite contiene come sottoinsieme la classe mentre da origine ad un sottoinsieme contenuto nella "classe originaria"

    class ThreePoint extends Point {
        protected double z;    /*   the z coordinate of the point  */
        ThreePoint() {      /*   default constructor  */
            x = 0.0;        /*   initialize the coordinates  */
            y = 0.0;
            z = 0.0;
        }

        ThreePoint(double x, double y, double z) {/*  specific constructor */
            this.x = x;        /*   initialize the coordinates  */
            this.y = y;
            this.z = z;
        }
    }

La parola extend impartisce al compilatore Java il comando di considerare la classe ThreePoint come una sottoclasse di Point. Essendo una estensione \xE8 necessario definire solo la "istance variable" z, e perch\xE8 questo possa accadere le variabili si stato debbono essere definite come protected in modo che siano disponibili a tutte le sotto-classi. Un altra modalit\xE0 di accesso alle variabili di stato della superclasse verr\xE0 definito nel punto successivo attraverso la parola chiave super
 class Point extends Object {
        protected double  x;    /*  instance variable  */
        protected double  y;    /* instance variable  */
        Point() {    /* constructor to initialize to zero  */
            x = 0.0;
            y = 0.0;
        }
    }
class ThreePoint extends Point 
{   
        protected double z;       /*   the z coordinate of the point  */
        ThreePoint() 
        {                                     /*  default constructor  */
            x = 0.0;                      /*   initialize the coordinates  */
            y = 0.0;
            z = 0.0;
         }
        ThreePoint(double x, double y, double z) 
         {                                      /*  specific constructor */
              this.x = x;                    /* initialize the coordinates  */
              this.y = y;
              this.z = z;
          }
    }

Ereditariet\xE0 Singola

Ogni sottoclasse pu\xF2 avere solo una classe di livello superiore cio\xE8 pu\xE0 essere estensione di una sola classe.

Override e super

Nella definizione di una sottoclasse pu\xF2 essere necessario "sostituire" (override=scavalcare) un metodo della superclasse, quindi tutti gli elementi del sottoinisieme definito dalla sottoclasse faranno riferimento al nuovo metodo. Si avr\xE0 sicuramente all'interno del codice della sottoclasse la necessit\xE0 di riferirsi al metodo della super classe e questo lo si fa con la parola chiave super
public class Subclass extends Superclass {
    // overrides printMethod in Superclass
    public void printMethod() {
        super.printMethod();
        System.out.println("Printed in Subclass");
    }
    public static void main(String[] args) {
        Subclass s = new Subclass();
        s.printMethod();    
    }
}

La chiamata al metodo constructror della superclasse pu\xF2 essere fatto con una sintassi pi\xF9 semplice come la seguente in cui la chiamata al metodo super deve trovarsi nella prima riga del constructor della sottoclasse
public MountainBike(int startHeight, 
                    int startCadence,
                    int startSpeed,
                    int startGear) {
    super(startCadence, startSpeed, startGear);
    seatHeight = startHeight;
}

Metodi e Messaggi

Usando il paradigma del passaggio di messaggi tra le varie classi si pu\xF2 cambiare il valore delle variabili di stato e quindi organizzare il funzionamento del programma. Questo obiettivo viene raggiunto attraverso la definizione di opportuni metodi.

Accessor Method

I metodi Accessor permettono di accedere alle informazioni che difiniscono l'oggetto sia per poterle modificare che per leggerle

Qui un esempio di un metodo definito per impostare i valori delle variabili di stato della classe Point, dove le variabili tornano ad essere private

    class Point extends Object {
        private double  x;    /*  instance variable  */
        private double  y;    /*  instance variable  */
        Point() {    /*  constructor to initialize to zero  */
            x = 0.0;
            y = 0.0;
        }
/*  constructor to initialize to specific value  */
        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }
        public void setX(double x) {    /*  accessor method  */
            this.x = x;
        }
        public void setY(double y) {    /*  accessor method  */
            this.y = y;
        }
        public double getX() {    /* accessor method  */
            return x;
        }
        public double getY() {    /* accessor method  */
            return y;
        }
    }

Variabili di Classe (Class Variables)

Le variabili di classe sono varibaili interne al codice che definisce la classe non ne definiscono lo stato quindi la generazione di un oggetto di quella classe non implica la presenza di tali variabili all'interno dell'oggetto creato, come invece avviene nel caso delle variabili di stato . Per definire una variabile di classe (Class variable) o un metodo di classe (Class Method) si usa la parola chiave static

    class Rectangle extends Object {            
        static  final int version = 2;
        static  final int revision = 0;
  }

Classi "Generiche" (Abstract Classes)

Le classi generiche permettono di definire l'insieme universo per una determinata categoria di oggetti come possono essere gli oggetti grafici.

Grafo pu\xF2 essere una classe Generica o Astratta che contiene tutti gli oggetti come Rettangolo, Cerchio, Punto, ecc.. Il predicato contiene sintetizza la definizione delle variabili di stato e dei metodi comuni a tutte le classi derivate da questa classe astratta.

abstract class Graphical extends Object {
    protected Point lowerLeft;     //  lower left of bounding box
    protected Point upperRight;    //  upper right of bounding box
.....              
more instance variables
....
    public void setPosition(Point ll, Point ur) {
        lowerLeft = ll;
        upperRight = ur;
    }
    abstract void drawMyself();   //   abstract method
}

Interfacce (Interface)

La parola chiave interaface identifica un insieme di codice il cui fine \xE8 quello di definire un contratto cio\xE8 una "descrizione informale del fine/significato" dei metodi. A tale scopo un'interfaccia, che \xE8 simile ad una classe, pu\xF2 contenere solo metodi, astratti o costanti. Non pu\xF2 contenere "..costruttori, variabili statiche, variabili di istanza e metodi statici..." ( Vedi Romani Universit\xE0 di Pisa )

Mentre una sottoclasse estende una classe un'interfaccia pu\xF2 essere implementata da un metodo che necessariamente \xE8 pubblico.

Le relazioni extends e implements

Ogni classe estende (extends) una sola altra classe (Object se non specificata); Una interfaccia pu\xF2 estendere (extends) una o pi\xF9 interfacce:

public interface <Int> extends <Int1>,<Int2>, ...{ 
     ... 
}

La gerarchia di ereditariet\xE0 singola delle classi e la gerarchia di ereditariet\xE0 multipla delle interfacce sono completamente disgiunte. Una classe pu\xF2 implementare (implements) una o pi\xF9 interfacce:

public class <nomeClasse> extends <nomeSuperClasse> 
       implements <Int1>, <Int2>, ..., <Intn> {
    ... 
}

In questo caso deve fornire una realizzazione per tutti i metodi delle interfacce , , ... che implementa, nonch\xE9 per i metodi di eventuali super-interfacce da cui queste eredita.

Attraverso questo meccanismo il compito di scrittura dell'interfaccia e quello del codice che la utilizza possono svolgersi in modo autonomo. La modifica del codice di un'interfaccia se fatto nel rispetto del contratto non richiede la modifica del codice che la utilizza.

Fine

-- RobertoBernetti - 19 Dec 2013

This topic: Informatica > WebHome > ProgrammazioneJava
Topic revision: 22 Feb 2017, UnknownUser
This site is powered by FoswikiCreative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License1999-2025
Ideas, requests, problems regarding this site? Send feedback