Visualizzazione dei risultati da 1 a 10 su 10

Discussione: classi innestate

  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315

    classi innestate

    Sto studiando le classi innestate e stavo guardando un esempio:
    codice:
    public class AutoNoInner
    {
        private String statoMotore;
        private MeccanicoNoInner meccanico;
    
        public AutoNoInner()
        {
            meccanico = new MeccanicoNoInner(this);
        }
        
        public void setStatoMotore(String statoMotore)
        {
            this.statoMotore = statoMotore;
        }
        
        public String getStatoMotore()
        {
            return statoMotore;
        }
    }
    
    public class MeccanicoNoInner
    {
        private AutoNoInner auto;
        
        public MeccanicoNoInner (AutoNoInner auto)
        {
            this.auto = auto;
        }
    
        public void aggiustaMotore()
        {
            auto.setStatoMotore("buono");
        }
    }
    Il manuale dice che utilizzando una classe innestata la situazione si semplifica molto:
    codice:
    public class Auto
    {
        private String statoMotore;
        
        public class Meccanico    
        {
            public void aggiustaMotore()
            {
                statoMotore = "buono";
            }
        }    
    }

    Io però non riesco a capire come possa trasformare così quella classe. Dove sono finiti i costruttori di Auto e Meccanico?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    Dove sono finiti i costruttori di Auto e Meccanico?
    Se il programmatore non definisce alcun costruttore per una classe, il compilatore ne genera uno di "default". Questo vale in generale e non c'entra con le inner/nested class.

    Comunque Meccanico è una "inner" class di Auto (non una nested "static" class), pertanto per poter istanziare Meccanico bisognerebbe avere una istanza di Auto (non puoi istanziare Meccanico così dal nulla).
    Queste classi che hai postato sono abbastanza fittizie giusto forse solo per far vedere le questioni con le classi innestate ma probabilmente hanno poco senso in realtà.
    Ultima modifica di andbin; 20-11-2014 a 13:11
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Se il programmatore non definisce alcun costruttore per una classe, il compilatore ne genera uno di "default". Questo vale in generale e non c'entra con le inner/nested class.
    ok, però i costruttori di default che vengono creati per Auto e Meccanico non farebbero le stesse operazioni dei costruttori definiti per AutoNoInner e MeccanicoNoInner. E' quello che non riesco a capire, come possa rimpiazzare dei costruttori non di default con dei costruttori di default ed ottenere lo stesso risultato.

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Comunque Meccanico è una "inner" class di Auto (non una nested "static" class)
    Ma che differenza c'è tra una inner class e una nested class?
    Inoltre mi sfugge il concetto di classe statica. Mi è chiaro il concetto di attributo statico (condiviso da tutti gli oggetti della classe) e di metodo statico (metodo che appartiene alla classe e non all'oggetto, quindi se non erro è invocabile con la sintassi NomeClasse.nomeMetodoStatico(); ), ma mi sfugge quello di classe statica.

    Quote Originariamente inviata da andbin Visualizza il messaggio
    pertanto per poter istanziare Meccanico bisognerebbe avere una istanza di Auto (non puoi istanziare Meccanico così dal nulla).
    si infatti, dovrei istanziare prima un oggetto di Auto:
    Auto auto = new Auto();
    e poi un oggetto di Meccanico ma sfruttando l'oggetto di Auto creato prima:
    Auto.Meccanico meccanico = auto.new Meccanico();

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    ok, però i costruttori di default che vengono creati per Auto e Meccanico non farebbero le stesse operazioni dei costruttori definiti per AutoNoInner e MeccanicoNoInner. E' quello che non riesco a capire, come possa rimpiazzare dei costruttori non di default con dei costruttori di default ed ottenere lo stesso risultato.
    Il costruttore di "default" delle classi (escludiamo le classi anonime perché il costruttore è generato ed è più particolare) ha semplicemente queste caratteristiche:
    - è "no-arg", non ha parametri.
    - fa una invocazione super(); senza argomenti.
    - prende lo stesso livello di accesso della classe.

    Il programmatore può definirne uno esplicito praticamente uguale ... ovviamente non è quello di "default" in senso concettuale, perché sarebbe esplicitato.


    Quote Originariamente inviata da newutente Visualizza il messaggio
    Ma che differenza c'è tra una inner class e una nested class?
    Le "inner" class non sono static, ed esiste una relazione molto speciale tra la inner-class e la classe contenitore.
    Le "nested" class sono static e non esiste alcuna relazione "speciale" tra la nested class e la classe contenitore.

    Quote Originariamente inviata da newutente Visualizza il messaggio
    Inoltre mi sfugge il concetto di classe statica. Mi è chiaro il concetto di attributo statico (condiviso da tutti gli oggetti della classe) e di metodo statico (metodo che appartiene alla classe e non all'oggetto, quindi se non erro è invocabile con la sintassi NomeClasse.nomeMetodoStatico(); ), ma mi sfugge quello di classe statica.
    codice:
    public class A {
        public static class B { }
    }

    B è una nested class (non "inner"!). E la puoi istanziare facendo B b = new A.B();
    Non c'è bisogno di una istanza di A, come invece accade per le inner class.

    codice:
    public class A {
        public class B { }
    }

    B ora è una inner class. Devi fare:

    A a = new A();
    poi
    B b = a.new B();
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Il costruttore di "default" delle classi (escludiamo le classi anonime perché il costruttore è generato ed è più particolare) ha semplicemente queste caratteristiche:
    - è "no-arg", non ha parametri.
    - fa una invocazione super(); senza argomenti.
    - prende lo stesso livello di accesso della classe.

    Il programmatore può definirne uno esplicito praticamente uguale ... ovviamente non è quello di "default" in senso concettuale, perché sarebbe esplicitato.
    Scusa se insisto ma vorrei capire.
    I costruttori delle classi Auto e Meccanico nella prima versione dell'esempio sono fatti così:
    codice:
    public AutoNoInner()
    {  
            meccanico = new MeccanicoNoInner(this);
    }
    codice:
    public MeccanicoNoInner (AutoNoInner auto)
    {  
           this.auto = auto;
    }
    Sono costruttori che fanno cose ben precise. Come si possono rimpiazzare con dei costruttori di default?

    Quote Originariamente inviata da andbin Visualizza il messaggio
    - fa una invocazione super(); senza argomenti.
    parlando dell'esempio fatto da te il costruttore della classe B invoca quello della classe Object, non quello di A. Vero?

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Le "inner" class non sono static, ed esiste una relazione molto speciale tra la inner-class e la classe contenitore.
    Le "nested" class sono static e non esiste alcuna relazione "speciale" tra la nested class e la classe contenitore.

    codice:
    public class A {
        public static class B { }
    }

    B è una nested class (non "inner"!). E la puoi istanziare facendo B b = new A.B();
    Non c'è bisogno di una istanza di A, come invece accade per le inner class.

    codice:
    public class A {
        public class B { }
    }

    B ora è una inner class. Devi fare:

    A a = new A();
    poi
    B b = a.new B();
    Ora mi è più chiaro però mi sfugge ancora cosa è una classe statica. Ad esempio, un attributo statico è un attributo condiviso da tutti gli oggetti della classe, un metodo statico è un metodo condiviso da tutti gli oggetti (quindi ogni oggetto non invocata una "copia" del metodo ma si invoca sempre lo stesso). E la classe statica?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    Sono costruttori che fanno cose ben precise. Come si possono rimpiazzare con dei costruttori di default?
    Il costruttore di "default" e intendo appunto quello generato dal compilatore semplicemente non fa nulla di specifico, a parte invocare (come è d'obbligo che sia) il costruttore della super-classe tramite un super(); .
    Se nel costruttore devi fare qualcosa di "particolare", allora ovviamente non può essere il costruttore di "default" !

    E ricorda, non l'ho precisato prima ma è meglio farlo adesso, che un costruttore di "default" viene generato dal compilatore SOLO se tu programmatore non scrivi alcun costruttore esplicito. Se ne definisci almeno uno, anche con argomenti, il costruttore di default NON viene generato.

    Quote Originariamente inviata da newutente Visualizza il messaggio
    parlando dell'esempio fatto da te il costruttore della classe B invoca quello della classe Object, non quello di A. Vero?
    Nel caso della nested class ( new A.B() ), è il costruttore di B (e poi super-costruttore di Object) che viene invocato. La classe A non c'entra nulla qui se non per il fatto che nei riguardi di B fa un po' da "namespace".

    Nel caso della inner class, come hai visto, si deve istanziare A prima di poter istanziare B. Nel momento in cui istanzi B ( a.new B() ) idem viene invocato il costruttore di B (e poi di Object). A non c'entra nulla nel senso che avevi già istanziato prima un A.

    Quote Originariamente inviata da newutente Visualizza il messaggio
    Ora mi è più chiaro però mi sfugge ancora cosa è una classe statica. Ad esempio, un attributo statico è un attributo condiviso da tutti gli oggetti della classe, un metodo statico è un metodo condiviso da tutti gli oggetti (quindi ogni oggetto non invocata una "copia" del metodo ma si invoca sempre lo stesso). E la classe statica?
    Una nested ("static") class è semplicemente una classe senza alcuna particolarità se non per il fatto che è strutturalmente dichiarata dentro un'altra classe.
    Se la classe contenitore ha nome completamente qualificato es. com.pincopalla.Contenitore allora la nested class ha nome qualificato com.pincopalla.Contenitore.ClasseNested .
    Quindi è un po' da vedere come se ClasseNested fosse in un "namespace" composto dal nome della classe Contenitore.
    Ma alla fine è tutto lì, non ci sono altre particolarità riguardo istanziazione, uso ecc... di ClasseNested.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Se nel costruttore devi fare qualcosa di "particolare", allora ovviamente non può essere il costruttore di "default" !
    Forse inizio a capire...si spera almeno.
    Il pezzo di codice incriminato è questo:
    codice:
    public class Auto
    {
        private String statoMotore;
        
        public class Meccanico    
        {
            public void aggiustaMotore()
            {
                statoMotore = "buono";
            }
        }    
    }
    Io voglio utilizzare il metodo aggiustaMotore, anche perchè lo scopo è riparare l'auto.
    Così com'è, per definizione di classe innestata (e poichè non è statica), devo necessariamente creare prima un oggetto di Auto (e me ne frego di quello che fa il costruttore), poi un oggetto di Meccanico (e me ne frego anche qui di quello che fa il costruttore) e infine richiamo il metodo aggiustaMotore.
    Quindi andrebbero scritte queste righe:
    codice:
    Auto auto = new Auto();
    Auto.Meccanico meccanico = auto.new Meccanico();
    meccanico.aggiustaMotore();
    La classe innestata, inoltre, per definizione può accedere ai membri (anche quelli private) della classe che la contiene e quindi è lecita l'assegnazione che viene fatta a statoMotore all'interno del metodo aggiustaMotore.

    Tutto corretto?

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ma alla fine è tutto lì, non ci sono altre particolarità riguardo istanziazione, uso ecc... di ClasseNested.
    Ok, e se invece parliamo di classi statiche "normali" (cioè non innestate)? Cosa sono?
    Ultima modifica di newutente; 20-11-2014 a 18:23

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    Io voglio utilizzare il metodo aggiustaMotore, anche perchè lo scopo è riparare l'auto.
    Così com'è, per definizione di classe innestata (e poichè non è statica), devo necessariamente creare prima un oggetto di Auto (e me ne frego di quello che fa il costruttore), poi un oggetto di Meccanico (e me ne frego anche qui di quello che fa il costruttore) e infine richiamo il metodo aggiustaMotore.


    Quote Originariamente inviata da newutente Visualizza il messaggio
    Quindi andrebbero scritte queste righe:
    codice:
    Auto auto = new Auto();
    Auto.Meccanico meccanico = auto.new Meccanico();
    meccanico.aggiustaMotore();
    Corretto. E la variabile meccanico va appunto tipizzata come Auto.Meccanico se si è in una classe esterna a Auto.
    (prima nel mio esempio avevo scritto B b = a.new B(); ma ho solo omesso per dimenticanza mia che invece è A.B b = ...... )

    Quote Originariamente inviata da newutente Visualizza il messaggio
    La classe innestata, inoltre, per definizione può accedere ai membri (anche quelli private) della classe che la contiene e quindi è lecita l'assegnazione che viene fatta a statoMotore all'interno del metodo aggiustaMotore.
    Esatto, è proprio quella la relazione "speciale" tra inner-class e classe contenitore.

    Quote Originariamente inviata da newutente Visualizza il messaggio
    Ok, e se invece parliamo di classi statiche "normali" (cioè non innestate)? Cosa sono?
    Beh .... non esistono! Una classe "top-level" (non innestata, cioè non dichiarata dentro un altro tipo) NON può essere static.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    ok, benissimo. grazie per la chiarezza.

  10. #10
    ora è più chiaro anche a me grz

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.