Newsgroup: it.comp.java
Titolo: Prime armi: mi chiarite alcuni concetti per favore?

Ciao, finalmente sto studiando sul 'Thinking in Java' di Bruce...(Lee :D), e
vorrei alcuni chiarimenti per favore:
1.quando una classe viene dichiarata Abstract, dice Bruce, non si possono
derivare da essa altre classi ma se ne puň usare solamente l'interfaccia.
    Praticamente se io scrivo:
        abstract Ipercubo ( ) {
            ruota( );
            trasla( );
        }
    non posso fare una cosa del tipo:
        public class Cubo extends (o implements ora non ricordo) Ipercubo {
        ....
        ....
        }
    ma posso usare solamente i metodi ruota( ) e trasla( ), giusto? Mi
potete fare per favore un esempio completo?
2.  che vuol dire 'Crare un metodo abstract permette di mettere un metodo in
un'interfaccia senza essere costretti a fornire un corpo di codice
possibilmente senza senso per tale metodo.'?
3.'La parola chiave Interface porta il concetto di classe abstract un passo
in avanti, prevenendo ogni definizione di funzione.' Cioč?
4.Avrei anche da chiedervi come fa il compilatore di un linguaggio OO a
sapere quale porzione di codice eseguire nella chiamata ad una funzione, ma
non faccio la domanda :)
Vi ringrazio a tutti e bun lavoro.
___________________________
A.Alberto, detto Songohan - Roma

derivare da essa altre classi ma se ne può usare solamente l'interfaccia.
Sono certo che Eckel non abbia scritto esattamente così.
Infatti:
public abstract class Abstract
{
	public abstract void sampleMethod();
 
	public String getParent()
	{
		return "Abstract";
	}
}
class Impl extends Abstract
{
	public void sampleMethod()
	{
		System.out.println
			("Implementazione di sampleMethod();"+
			" dichiarato nella classe "+getParent()+".");
	}
	public static void main(String[] args)
	{
		Abstract abs=new Impl();
		abs.sampleMethod();
	}
}
compila ed esegue correttamente.
HTH,
Mauri.
-- 
La forza di gravità è un falso mito,
è la Terra che succhia!

 }
Allora ecco il testo originale: 'Often in a design, you want the base class
to present only an interface for its derived classes. That is, you don't
want anyone to actually create an object of the base class, only to upcast
to it so that its interface can be used. This is accomplished by making that
class abstract using abstract keyword. If anyone tries to make an object of
an abstract class, the compiler prevents them.'
Poichč sto alle prime armi con questi concetti, non č che potreste
spiegarmelo in parole un pň piů semplici? Grazie mille.
P.S. Dell'esempio non č che io abbia capito tutto :)

P.S. Dell'esempio non è che io abbia capito tutto :)
Credo che il modo migliore per capire un concetto del genere sia
vederlo applicato ad un caso concreto, e capire l'utilità di avere
classi astratte od interfacce sui cui metodi fare affidamento
*indipendentemente* dalle implementazioni.
Leggi del codice, troverai esempi lampanti.


 Abstract abs=new Impl();
Ah ecco...adesso mi è più chiaro...Non posso usare la keyword New su una
classe abstract ma devo prima usare Implements poi new sull'oggetto creato
da Implements.
Grazie.

da Implements.
Ci sei *quasi*.
Le classi abstract (che hanno metodi abstract ma *possono* avere
metodi con corpo) si *estendono* con la keyword extends, le interface
(che hanno *tutti* metodi abstract) si implementano con la keyword
implements.
Ciao,
Mauri.
P.s.: new va minuscolo... sii *sempre* case-sensitive, abituati...


Spero che i puristi e i più esperti mi perdoni per eventuali inesattezze.
Allora.
I concetti di classe ASTRATTA e INTERFACCIA sono quasi identici.
Le grosse differenze sono che :
Una classe ASTRATTA può essere solo estesa e può contenere del codice.
Puoi ad esempio creare una classe astratta che ha dei metodi già
implementati.
Le interfaccie NON possono contenere codice, ma solo la dichiarazione dei
metodi che poi dovranno essere implementati da chi la utilizza.
Le interfaccie se non erro possono contenere costanti.
Un' INTERFACCIA può essere estesa SOLO da un'altra INTERFACCIA.
Un' INTERFACCIA può essere SOLO IMPLEMENTATA da un'altra INTERFACCIA.
Una classe ASTRATTA può essere SOLO ESTESA, ma può implementare
un'interfaccia e può estendere un'altra classe ASTRATTA.
Le classi Astratte e le Interfaccie, non possono essere istanziate
direttamente, ma devono essere Implementate.
ATTENZIONE !!!!!!!!!!!!!!
Importatante, se estendi una classe astratta DEVI implementare TUTTI i
METODI ASTRATTI di quella classe.
Ovvio che quelli già implementati li puoi reimplementare solo se ti serve.
Se implementi un'Interfaccia, DEVI implementare tutta l'interfaccia.
Se non implemeti anche un solo metodo o dell'interfaccia o della classe
astratta, il compilatore ti da errore.
Se non erro ti segnala anche i metodi che non hai implementato.
Se ci sono dei metodi che non intendi utilizzare basta dichiarare il metodo
e poi lasciare vuoto il suo corpo.
Per evitare agli sviluppatori queste noie ci sono delle classi "concrete"
chiamate Adapter che implementano tutti i metodi di un listener (ovviamente
sono solo i metodi vuoti quindi non fanno nulla), ma ti evitano di
riscrivere ogni volta utto il codice.
Un esempio è la classe MouseAdapter che implementa l'interfaccia
MouseListener e che serve al metodo [addMouseListener()] dei vari oggetti
grafici.
Chiariti questi primi aspetti vediamo qualche esempio che chiarisce l'uso di
questi concetti.
Il concetto (a mio avviso) è lo stesso, il campo di utilizzo può variare
leggermente.
Immagina di fare una classe che permette di creare visualmente dei file PDF.
Ad un certo punto la devi salvare in qualche maniera.
Siccome non vuoi obbligare l'utente a salvarlo esclusivamente su un file
locale, quello che ti serve è un'interfaccia o una classe astratta che ti
fornisce i metodi giusti per "SALVARE" le informazioni, quello che poi
effettivamente faranno i dati cvhe gli passi, non lo sai e non te frega
niente.
Nel caso specifico, obbligherai lo sviluppatore che usa la tua classe a
passarti un "OutputStream" che è una classe astratta di Java.
Questa ti da tutti i giusti metodi per spedire le informazioni ad uno
Stream. Se poi chi implementa questa classe le spedisce su un file o lungo
la rete a te poco importa.
Questo è un'esempio abbastanza reale. Difatti la classe astratta
"OutputStream" viene implementata dalle classi "concrete" : [
BufferedOutputStream, ByteArrayOutputStream, DataOutputStream,
FilterOutputStream, FileOutputStream ].
Nel caso che hai proposto tu, puoi dichiarare un'Interfaccia con i metodi :
ruota(float gradi), muovi(int x, int y),
Poi dichiarare tante classi che la implementano:
public interface Sprite
{
    public void ruota(float nGradi);
    public void muovi(int x, int y);
}
public class Rettangolo implements Sprite
{
    public Rettangolo(int xPo, int Pos, int xSize, int ySize)
    {
        ...........................
        ............................
    }
    // Implementi i metodi dell'Interfaccia
    public void ruota(float nGradi)
    {
        ...........................
        ............................
    }
    public void muovi(int x, int y)
    {
        ...........................
        ............................
    }
}
public class Esagono implements Sprite
{
    //    stessa cosa di Rettangolo
}
public class Cerchio implements Sprite
{
    //    stessa cosa di Rettangolo
    // Ovvio che quì il metodo ruota è inutile
}
public class Engine2D
{
    Vector poligoni = new Vector();
    poligoni.addElement(new Cerchio(raggio));
    poligoni.addElement(new Cerchio(raggio*2));
    poligoni.addElement(new Rettangolo(10,10, 30,50));
    poligoni.addElement(new esagono(........));
//    ora basta recuperare dall vettore l'oggetto ed invocare su di esso il
metodo ruota o mouvi
}
A ricordati che questo è solo un codice di esempio, non provato.
Potresti migliorarlo sicuramente.
Spero di essere stato chiaro a sufficenza.
Ciao e fammi sapere.
santo...@NOSPAMNOROMPIciaoweb.it

 P.s.: new va minuscolo... sii *sempre* case-sensitive, abituati...
Si hai ragione...Sai provengo dal VB che non è una buona scuola....
Il Java lo sto trovando estremamente affascinante....poi come lo spiega
Bruce è fantastico anche se questo paragrafo sulle classi 'abstract' gli
suggerirò fi farlo meglio :DD
Cmq per le definizoni di cui sopra ne saprò di più sicuramente quando
inizierò lo studio vero e proprio della sintassi.
Grazie mille.
Ciao,
Alberto


Credo a questo punto che un bella panoramica sui concetti di classe ed
interfaccia mi debba essere fatta.
Una classe è una collezione di oggetti che hanno dei metodi e/o
comportamenti in comune.
Un'interfaccia è l'insieme dei metodi che possono essere richiesti ad un
particolare oggetto....Giusto?
Quindi per favore mi puoi chiarire quanto hai esposto? Ho una certa
confuzione in mente a riguardo.....
Grazie.

 particolare oggetto....Giusto?
L'interfaccia permette a oggetti diversi di essere adoperati alla stessa
maniera senza conoscere la loro natura.
Un uomo cammina diversamente da un elefante e da un leone, ma tutti e tre
camminano, quindi io posso semplicemente dire cammina, se poi chi riceve il
comando è un leone questo provvederà da se a camminare senza che a me freghi
nulla di come lo farà, basta che lo faccia.
Questo ti svincola ancche dal fatto di scrivere tutto il codice per tutte le
ipotetiche situazioni di utilizzo.
Tu fornisci dei metodi, poi gli altri ci fanno quello che gli pare.
Spero di non averti confuso ulteriormente.
Se vuoi scrivimi pure direttamente.
Se vuoi provare con esempi un pochino più concreti, prova a costruire una
classe che manda dei dati su un OutputStream (che è una classe Astratta),
poi cominci a passargli oggetti che implementano OutputStream
(BufferedOutputStream, ByteArrayOutputStream, DataOutputStream,
FilterOutputStream, FileOutputStream) e tutti ti si chiarirà all'istante.
Vedrai che senza conoscere l'implementazione di quelle classi, i tuoi dati
verranno utilizzati in maniera completamente diversa ma a te non sembrerà,
perché farai riferimento sempre a metodi generi.

 P.S. Dell'esempio non č che io abbia capito tutto :)
Il testo che hai riportato e' in effetti nebuloso per uno che 
si avvicina per la prima volta a Java in quanto qui Bruce Eckel 
cerca di spiegare uno dei modi in cui una classe astratta viene 
spesso progettata, cioe':
- la DEFINIZIONE di una interfaccia pubblica, costituita dai suoi
  metodi pubblici, dei quali la classe astratta fornisce anche una
  implementazione concreta
- la DICHIARAZIONE di una interfaccia astratta, per le classi concrete 
  da essa derivate, costituita generalmente da uno o piu' metodi
astratti 
  (spesso con modificatore protected)
I metodi pubblici definiti dalla classe astratta delegano parte della
loro
implementazione ai metodi astratti. 
Per dirla in un altro modo, gli algoritmi dei metodi pubblici utilizzano
i 
metodi astratti come dei call-back, che possono cosi' essere di volta in
volta 
implementati in modo differente dalle diverse implementazioni concrete.
Un esempio vale piu' di mille parole:
public abstract class Base
{
  // INTERFACCIA PUBBLICA: per gli utilizzatori
  public void faiQualcosa()
  {
     // Alcuni statement 
     System.out.println("PRIMA dell'invocazione del callback astratto");
     // DELEGA una parte dell'algoritmo alle implementazioni concrete
     faiQualcosaCallBack();
     // Altri statement
     System.out.println("DOPO l'invocazione del callback astratto");
  }
  // INTERFACCIA PROTETTA E ASTRATTA: per le implementazioni concrete
  protected abstract void faiQualcosaCallBack();
}
public class Derived1 extends Base
{
   // Implementazione concreta dell'interfaccia astratta
   protected void faiQualcosaCallBack()
   {
     System.out.println("CALLBACK: implementazione di " +
getClass().getName());
   }
}
public class Derived2 extends Base
{
   // Implementazione concreta dell'interfaccia astratta
   protected void faiQualcosaCallBack()
   {
     System.out.println("CALLBACK: implementazione di " +
getClass().getName());
   }
}
public class Tester
{
    public void test(Base base)
    {
       base.faiQualcosa();
    }
    public void main(String[] args)
    {
         Derived1 d1 = new Derived1();
         Derived2 d2 = new Derived2();
         Tester t = new Tester();
         t1.test(d1);
         t1.test(d2);       
    }
}
Come vedi, la classe Base espone l'interfaccia pubblica e concreta per i
suoi
utilizzatori, mentre l'interfaccia protetta e astratta e' ad uso delle 
implementazioni concrete.
La classe Tester NON PUO' creare istanze di Base perche', in quanto
astratta,
manca di alcuni "pezzi": i metodi astratti!
Tester crea istanze delle implementazioni concrete e le utilizza tramite
la loro
interfaccia pubblica comune (il metodo faiQualcosa()). Cio' che viene
prodotto in
output cambia a seconda della implementazione concreta che viene
utilizzata,
perche' ciascuna implementa a proprio modo la parte astratta.
Questo tipo di design fornisce flessibilita': il metodo test() della
classe Tester puo' funzionare SENZA MODIFICHE E/O RICOMPILAZIONI, con
una 
qualsiasi implementazione concreta (PRESENTE E FUTURA) della classe
Base.
Nota anche che nell'esempio, rimane la dipendenza tra la classe Tester e
le classi concrete a causa del metodo main() che le crea: in un progetto
reale, 
tale dipendenza, se indesiderata, puo' essere facilmente rimossa
delegando ad
un'altra classe la responsabilita' di creare le implementazioni concrete
(per gli esperti, usando il pattern FactoryMethod oppure un
AbstractFactory) 
Ovviamente il discorso sull'impiego delle classi astratte e delle
interfacce
e' alquanto piu' esteso, ma non mi sembrava il caso di aggiungere
ulteriori 
complicazioni.
Spero comunque di aver chiarito qualche aspetto importante.
Saluti
Roberto
-- 
+---------------------------+
| Roberto Bagnoli           |
| 
robe...@comune.modena.it
 |
+---------------------------+

 P.S. Dell'esempio non č che io abbia capito tutto :)


 P.S. Dell'esempio non č che io abbia capito tutto :)
