|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Sep 2004
Città: Sardegna
Messaggi: 98
|
[JAVA] Istanziare un oggetto di una classe interna
Ciao a tutti! Ho un problema:
sto creando 2 classi (BonusVita e BonusVelocità) interne ad una classe madre Bonus. Vorrei istanziare dall'esterno (dalla classe Game) degli oggetti di tipo BonusVita e BonusVelocità,non posso farlo? Ho pensato anche di creare come classi esterne le 2 classi BonusVita e BonusVelocità facendogli estendere a entrambe la classe Bonus (da cui devono ereditare tutti i metodi e le variabili), ma non mi sembra la soluzione ottimale (sarebbe più facile da implementare ma vorrei fare la cosa più "lineare" a livello progettuale), dato che queste classi risulterebbero piccolissime, con solo un metodo. Potete darmi qualche consiglio? |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
Quote:
in bonus fai un createBonusVita e createBonusVelocita, entrambti statici che creano la classe. ps.e buona norma di solito fare una classe per .java e usare il meno possibile classi interne, cmq fai tu il fatto che siano piccole non è un problema |
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quindi: Codice:
Bonus b = new Bonus (); // istanza di Bonus ... Bonus.BonusVita vita = b.new BonusVita (); Bonus.BonusVelocita velocita = b.new BonusVelocita ();
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se la classe Y è interna ad X ma non annidata la sintassi è:
X.Y y = x.new Y(); con x riferimento ad un'istanza di X. Se la classe Y è annidata in X la sintassi è: X.Y y = new X.Y(); Una classe interna (inner) è annidata (nested) se è dichiarata static. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Stavo scrivendo quando ha risposto Andbin... ma un bel semaforone che dica "guarda, o' grullo d'un pgi, che qualcuno ha già risposto mentre tu stai qui a cincischiare" non farebbe comodo?
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Per la parte "progettuale" la questione top-level, inner o nested non è difficile da spiegare ma neppure breve. Se hai il tempo di leggere una risposta-papiro posso scriverla.
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
Quote:
|
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2005
Messaggi: 897
|
Secondo me ti conviene di + creare tutte classi separate.... sarà che ho una visione di java molto OO
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Poco dopo la scomparsa dei dinosauri... A me preme sempre l'esigenza di spiegare l'utilità degli strumenti offerti da un linguaggio ai fini della produzione di un sistema orientato agli oggetti e non, talvolta capita di sentirlo, di spiegare l'orientamento agli oggetti attraverso gli strumenti offerti da un linguaggio. Credo quindi che occorra vedere cosa facciano quegli strumenti, secondo le loro regole, e poi cercare di capire se essi occupino o non occupino una qualche casella della prospettiva orientata agli oggetti. Insomma: è Java che mira ad essere orientato agli oggetti e non l'orientamento agli oggetti ad essere Java (o C++ o Python e persino Smalltalk). Io penso che l'orientamento agli oggetti possa essere spiegato con l'ausilio di due soli termini: oggetto e relazione. Oggetto è qualsiasi cosa di cui sia predicabile l'identità esclusiva con sè stesso. La relazione è un predicato riferibile ad uno o più oggetti. L'unicità della relazione (un certo predicato e non un altro) rende la relazione stessa un oggetto. Una classe Java è il modello a partire dal quale sono prodotti dei valori tipizzati detti istanze. Tutte le istanze prodotte da un medesimo modello sono accomunate dal possesso di un insieme strutturalmente identico di elementi (membri, enfaticamente detti "di istanza" perchè ciò che non è "di istanza" non è membro). Una classe Java appare quindi idonea a rappresentare il concetto di relazione. Una classe Java è la relazione che intercorre tra tutti gli oggetti che ne siano istanza. Una bizzarria: secondo la teoria delll'orientamento agli oggetti su descritta una classe Java, in quanto relazione, è anche un oggetto. Ma non andate a dirlo in giro Poichè ogni relazione è un oggetto e ogni relazione è un predicato riferibile ad uno o più oggetti, nulla vieta che esista una relazione tra relazioni ed una relazione tra un oggetto ed una relazione. Detto questo e premesso che in Java una classe interna è una classe annidata, non esplicitamente o implicitamente dichiarata static, quali sono le caratteristiche di una classe Java interna? La sua dichiarazione interviene all'interno del corpo di un'altra classe: Codice:
class TopLevel {
class Inner() {}
}
Codice:
class TopLevel {
private int x;
private TopLevel() {}
class Inner() {
Inner() {
TopLevel t = new TopLevel();
t.x = 20;
x = 40;
}
}
}
Ogni istanza della classe interna è associata ad un'istanza della classe che la contiene (quella usata all'atto della creazione). Codice:
public class TopLevel {
public class Inner() {
TopLevel getOwner() {
return TopLevel.this;
}
}
}
TopLevel top = new TopLevel();
TopLevel.Inner inner = top.new Inner();
//top == inner.getOwner()
Come ogni classe Java la classe interna è una relazione tra tutte le sue istanze. Sotto questo profilo è quindi adatta a rappresentare l'insieme di caratteristiche che accomunano degli elementi in un sistema di riferimento. Ma per rappresentare una relazione tout-court, in Java, c'è già lo strumento classe top-level che è anche più semplice da usare. Se lo scopo è quindi quello di dichiarare delle categorie di oggetti – BonusVista e BonusVelocità – allora lo strumento Java apparentemente più idoneo è la classe top-level. Ogni istanza di Inner è collegata ad un'istanza di TopLevel. Ogni inner è funzionalmente collegato ad un outer. Più inner possono essere collegati allo stesso outer. Astrattamente è una caratteristica molto (ma molto, ma mi viene da dire "ohhh com'è molto") interessante. Nel sistema di riferimento tra uno o più BonusVita e un Bonus e tra uno o più BonusVelocità e un Bonus esiste qualche collegamento funzionale? Capita che un BonusVelocità deva fare qualcosa sempre sullo stesso Bonus e che più BonusVelocità vogliano farlo sullo stesso Bonus? Se sì allora la classe Java interna è uno strumento intimamente idoneo a rappresentare quella relazione. Personalmente non vedo una relazione di questo genere tra BonusVita e Bonus o tra BonusVelocità e Bonus ma non posso escludere che effettivamente vi sia. E' rilevante la dipendenza "semantica" della classe interna dalla classe che la contiene? Per intenderci, il fatto che un inner non sia semplicemente un Inner ma abbia il segno TopLevel.Inner? Be', è senz'altro un predicato comune a più oggetti. Dunque se scrivo: Codice:
public class Macchina {
public class Motore {}
}
dico che esiste una relazione tra Macchina e Motore nominalmente espressa in Java con Macchina.Motore, tipo delle istanze di Motore. Tuttavia se la relazione che si vuole esprimere è interamente rappresentabile con la sola dipendenza nominale, la parte relativa al collegamento tra le istanze è un significato che ci si porta dietro anche se non ce ne importa nulla. Codice:
public class Aeroplano {
public class Mela {
}
}
Conclusione sulle classi interne (rullo di tamburi!): Ogni classe Java interna è una relazione univoca tra una relazione ed un oggetto (funzionale) e una relazione biunivoca tra relazioni (nominale). Classi annidate (non interne). E' una classe dichiarata static all'interno di un'altra classe o interfaccia (le interfacce annidate non sono mai interne). Codice:
public class TopLevel {
public static class Nested {
}
}
Per creare un'istanza di Nested non è necessario disporre di un riferimento TopLevel. Codice:
TopLevel.Nested nested = new TopLevel.Nested(); Nested è una classe Java. La domanda è la stessa che ci siamo fatti per le classi inner: date le caratteristiche della classe annidata risulta utile all'espressione di relazioni o oggetti? Come per la classe interna, anche la classe annidata è idonea a rappresentare una relazione generica. Abbiamo però visto che è più conveniente rappresentare questo fatto con una classe TopLevel. Tanto per essere chiari in questi due casi: Codice:
public class Pippo {
}
Codice:
public class TopLevel {
public static class Pippo {
}
}
Manca il collegamento molto molto interessante tra l'istanza della classe TopLevel e le istanze di Nested che avevamo ravvisato nel caso TopLevel-Inner. C'è ancora quella relazione "nominale": un Nested non è semplicemente tale ma è un TopLevel.Nested. E qui la cosa si fa interessante (soprattutto per caralu). A differenza del caso delle classi interne una classe annidata esprime una relazione nominale "pura". Solo "barba e capelli", per tornare alla metafora del barbiere. La relazione nominale pura è il tipo più semplice di relazione che si può ravvisare in un sistema quando lo si osservi con gli occhi dell'orientamento agli oggetti. "Quelle due cose lì hanno un che di comune. Cosa? Non lo so ma qualcosa ce l'hanno". Ci spari una relazione nominale Conclusione. Una classe Java annidata esprime una relazione tra relazioni (nominale tra la classe annidata e la classe continente). Il caso di caralu è emblematico. BonusVita e BonusVelocità hanno qualcosa in comune? Voilà: Codice:
public class Bonus {
public static class BonusVita {}
public static class BonusVelocità {}
}
Codice:
public class Bonus {
public static class BonusVita extends Bonus {}
public static class BonusVelocità extends Bonus {}
}
Codice:
public class Bonus {
public static class BonusVita {}
public static class BonusVelocità {}
}
Codice:
public class Bonus {}
public class BonusVita extends Bonus {}
public class BonusVelocità extends Bonus {}
Codice:
public class Bonus {
public static class BonusVita extends Bonus {}
public static class BonusVelocità extends Bonus {}
}
Con l'annidamento si fanno tante cose interessanti. Una sfrutta anche il fatto che l'annidato veda cose che gli altri non vedono. Supponiamo di avere un immutable: Codice:
public final class Giovannone {
private final String nome, cognome, soprannome, nomignolo;
Codice:
public final class Giovannone {
private final String nome, cognome, soprannome, nomignolo;
public Giovannone(String nome, String cognome, String soprannome, String nomignolo) {
this.nome = nome;
this.cognome = cognome;
this.soprannome = soprannome;
this.nomignolo = nomignolo;
}
public String getNome() {
return nome;
}
public String getCognome() {
return cognome;
}
public String getSoprannome() {
return soprannome;
}
public String getNomignolo() {
return nomignolo;
}
}
Codice:
Giovannone g = new Giovannone("Giò", "Gì", "Giù", "Già");
Codice:
public final class Giovannone {
private final String nome, cognome, soprannome, nomignolo;
public Giovannone(Data data) {
this.nome = data.nome;
this.cognome = data.cognome;
this.soprannome = data.soprannome;
this.nomignolo = data.nomignolo;
}
public String getNome() {
return nome;
}
public String getCognome() {
return cognome;
}
public String getSoprannome() {
return soprannome;
}
public String getNomignolo() {
return nomignolo;
}
public static class Data {
private String nome, cognome, soprannome, nomignolo;
public void setNome(String v) {
nome = v;
}
public void setCognome(String v) {
cognome = v;
}
public void setSoprannome(String v) {
soprannome = v;
}
public void setNomignolo(String v) {
nomignolo = v;
}
}
}
Codice:
Giovannone.Data data = new Giovannone.Data();
data.setNome("Giò");
data.setCognome("Gì");
data.setSoprannome("Giù");
data.setNomignolo("Già");
Giovannone g = new Giovannone(data);
E voi, pochi e accaniti sopravvissuti a queste brevi riflessioni |
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
Quote:
![]() ps.in caso di costruttori con n mila parametri la cosa potrebbe aver senso, ma la stessa cosa si puo ottenere con una classe esterna, ma in effetti ci vuole piu codice(getter & setter, invece che soli setter) per la classe data. per quanto riguarda le inner class, si sono potenti per il fatto che riescono ad accedere ai membri private della classe top, ma preferisco girare attorno a questo limite in altra maniera per evitare di avere 2 classi in un unico .java. Potrebbe venire interessante per una classe astratta, di cui bisogna implementare uno o due metodi che debbano accedere alla parte privata della top-class, ma non so manco se funziona
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Avevo il forte sospetto che non sarei riuscito a spiegarmi. Be' com'è il detto: meglio aver tentato e fallito che non aver tentato affatto
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
Quote:
|
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Scusa, ma io ho sempre sentito che inner e nested sono sinonimi,
dove hai letto la distinzione?
__________________
|Java Base| |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
E' scritto nelle specifiche del linguaggio di programmazione Java (The Java Language Specifications, 3th edition, introduzione al capitolo 8, secondo paragrafo, p. 173 e capitolo 8.1.3, primo paragrafo, p. 181)
|
|
|
|
|
|
#15 | |
|
Member
Iscritto dal: Sep 2004
Città: Sardegna
Messaggi: 98
|
Quote:
JAVA: fondamenti di progettazione software di Lewis & Loftus, cap.5 pag.228 |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jul 2002
Messaggi: 4334
|
Grazie.
__________________
|Java Base| |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Non sono un fenomeno con Java, ma la spiegazione di PGI-Bis mi pare molto ben fatta, almeno, io ho capito..
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:06.












|








