PDA

View Full Version : Java: questa è indigesta


misterx
24-04-2007, 20:50
le istanze di una metaclasse sono classi e vengono risolte a compile-time....

ma cos'è una metaclasse ?

da quanto ho scritto sopra, mi viene in mente la vecchia struttura di C dove, se pensiamo alle classi nelle OOP alle vecchie strutture, con metaclasse è come se dicessi che una struttura alloca(istanzia/stampa etc...) un'altra struttura in memoria.....boh.

ma esiste anche il livello meta-meta

andbin
24-04-2007, 21:25
le istanze di una metaclasse sono classi e vengono risolte a compile-time....

ma cos'è una metaclasse ?

da quanto ho scritto sopra, mi viene in mente la vecchia struttura di C dove, se pensiamo alle classi nelle OOP alle vecchie strutture, con metaclasse è come se dicessi che una struttura alloca(istanzia/stampa etc...) un'altra struttura in memoria.....boh.

ma esiste anche il livello meta-metaNon ho ben capito .... ti riferisci alla "reflection", dove certe classi come Class, Method, Field (e altre) permettono di descrivere la struttura delle classi???

misterx
24-04-2007, 21:43
Non ho ben capito .... ti riferisci alla "reflection", dove certe classi come Class, Method, Field (e altre) permettono di descrivere la struttura delle classi???

è una definizione che ho trovato in rete per metaclasse.
So di non essere molto chiaro in quanto conosco poco l'argomento; quanto ho scritto sono solo delle ipotesi.

Tu sai cosa si intende per metaclasse ?
e poi:
livello meta-meta classe
livello meta classe
livello classe
livello oggetto

PGI-Bis
25-04-2007, 00:14
E' terminologia nata con Smalltalk. Dai un'occhiata all'ultimo capitolo di "Smalltalk and Object Orientation" di Jhon Hunt (credo).

misterx
25-04-2007, 07:25
E' terminologia nata con Smalltalk. Dai un'occhiata all'ultimo capitolo di "Smalltalk and Object Orientation" di Jhon Hunt (credo).

immaginavo che da qualche parte fossero nate tali terminologie, gli darò subito un occhio, magari trovo anche cose del tipo: semantica type-instance

misterx
25-04-2007, 14:18
scusate ma non mi ricordo se in java una superclasse può usare metodi delle sue sottoclassi e, se tale pratica avrebbe senso

PGI-Bis
25-04-2007, 15:05
Sarebbe una mostruosità.

Mentre una figlia ha sempre una classe madre, una classe può non avere figlie.

misterx
27-04-2007, 16:33
grazie PGI

altra domanda

Se implemento una classe astratta ed un metodo astratto esempio:

public abstract class Figura ;
{
public abstract void AreaFigura();
}

ora implemento le classi concrete cerchio, rettangolo, triangolo che implementano il metodo AreaFigura domada: sto implementando il metodo della classe astratta in modo polimorfo ?

IO credo di si in quanto poi ogni classe della relativa figura userà il proprio metodo per calcolare l'area della propria istanza :stordita:

PGI-Bis
27-04-2007, 17:32
Un metodo è polimorfico se è applicabile ad operandi di più tipi, diversi da quello dichiarato. In Java, ogni metodo ereditabile è per definizione polimorfico in quanto applicabile a valori del tipo in cui è dichiarato e ad ogni suo sottotipo. E questo vale a prescindere dal fatto che tale metodo sia o non sia astratto.

misterx
27-04-2007, 21:40
forse non mi sono spiegato bene.
Posso avere anche una superclasse A concreta ed alcune sottoclassi come ad esempio B, C, D che sovrascrivono (overriding) il metodo della loro superclasse. In questo caso sto parlando di polimorfismo, giusto ?

Mi interessava solo comprendere se il mio agire è implementare il polimorfismo; a me pare di si in quanto la chiamata del metodo è il medesimo, ma fa cose leggermente diverse in funzione delle varie implementazioni(cerchio, rettangolo, triangolo).

PGI-Bis
27-04-2007, 23:39
Forse sono stato io ad essere sibillino.

Il polimorfiso è la capacità di un'espressione di avere più di un tipo.

Un metodo polimorfo è un metodo i cui operandi possono essere di più di un tipo.

Un tipo polimorfo è un tipo le cui operazioni possono essere applicate a più di un tipo.

Il tuo tipo Figura è polimorfo perchè le sue operazioni possono essere applicate a più di un tipo (a Figura e ad ogni sottotipo di Figura).

Il tuo metodo AreaFigura è polimorfo perchè i suoi operandi possono essere di più di un tipo (ancora Figura ed ogni sottotipo di figura).

Se limitiamo il concetto di operando ai parametri richiesti da un metodo, allora il metodo AreaFigura è monomorfo.

Il fatto che il metodo AreaFigura possa essere sovrascritto è irrilevante: il polimorfismo è una questione di tipi, non di comportamenti.

misterx
28-04-2007, 06:28
scusa PGI ma da come lo scrivi(e di sicuro capisco male io) sembra che un metodo definito in una superclasse può essere usato in tutte le sue sottoclassi(oggetti differenti), ma questa è l'ereditarietà.

Tenendo in considerazione l'ereditarietà, ora, se ogni classe sovrascrive il metodo ereditato(overriding), parliamo di polimorfismo e viene eseguito il metodo corretto, anche se il nome del metodo è il medesimo, della classe che ha generato l'oggetto.

Dal lato utilizzatore, noi usiamo il metodo AreaFigura senza interessarci di quale verrà usato.

PGI-Bis
28-04-2007, 10:16
Per un linguaggio orientato agli oggetti il polimorfismo dei metodi è una conseguenza dell'ereditarietà.

Dai un'occhiata a Cardelli-Wegner, On Understanding Data Types, Abstraction and Polymorphism.

misterx
28-04-2007, 10:31
grazie PGI, credo di aver capito.

Per cosa vengono usati isKindOf e isTypeOf ?
E quali sono le differenze ?

PGI-Bis
28-04-2007, 11:50
isKindOf è come instanceof

print := [:value | Transcript show: value; cr.].
printTrue := [print value: 'è una stringa'.].
printFalse := [print value: 'non è una stringa'.].
var := String new.
(var isKindOf: String) ifTrue: printTrue; ifFalse: printFalse.

isTypeOf non so cosa sia. L'interpretazione letterale suggerisce che:

(aClass isTypeOf: anObject)

valga vero se aClass è tipo o supertipo di anObject e falso in caso contrario. Ma, ripeto, non mi pare sia un metodo standard della piattaforma Smalltak.

misterx
28-04-2007, 12:14
edit

Griffo
28-04-2007, 12:22
o santa pazienza.....

Ma supertipo è sinonimo di superclasse ? :muro:

Non sempre. Per esempio nel caso dei tipi primitivi long è supertipo di int ma non è una superclasse di int (anzi non è neanche una classe)

PGI-Bis
28-04-2007, 12:24
I termini propri sono tipo, supertipo e sottotipo.

misterx
28-04-2007, 12:26
mi avete anticipato..

Supertipo rappresenta un tipo riferimento dove ad esempio se scrivo:

o Object;
r Rettangolo;

posso istanziare un rettangolo anche usando come riferimento o in quanto è supertipo di r, giusto ?


PGI, la storia del isTypeOf(C).....e isKindOF(C).... nasce da queste affermazioni che ancora non ho del tutto digerito:

Classi di implementazione: ogni oggetto o ha un’unica classe implementativa, che ne definisce i metodi; quindi scriveremo:
o : IsTypeOF(C)
• Classi come tipo: un oggetto o ha classe C se C è la classe implementativa di o, o C generalizza la classe implementativa di o; quindi scriveremo:
o : IsKindOf(C)
• In UML o:C significa o : IsKindOf(C)

PGI-Bis
28-04-2007, 12:34
L'idea è corretta ma l'espressione andrebbe raffinata. Quello che puoi fare non è creare un'istanza di un Rettangolo usando un Object ma assegnare ad un Object un'istanza di Rettangolo.

Perchè puoi farlo? Perchè il tipo Object è polimorfo.

E colgo l'occasione del messaggio di griffo per dire: si noti come pur essendo long supertipo di int, long non sia polimorfo perchè se è vero che il linguaggio Java accetta l'enunciato:

int x = 10;
long y = x;

le norme del linguaggio dicono anche che il valore restituito dall'espressione x è soggetto ad una conversione implicita prima dell'assegnamento e la conversione non è polimorfismo.

PGI-Bis
28-04-2007, 12:40
Occhio a generalizzare UML: non c'entra niente con l'orientamento agli oggetti. Lì devi leggere la cosa come:

o isTypeOf C

significa che o è istanza di C.

o isKindOf C

significa che o è istanza di C oppure è istanza di un sottotipo di C.

misterx
28-04-2007, 12:58
a che serve tale distinzione visto che, la seconda soluzione, isKindOf, copre entrambi i casi ?

Forse nel primo caso non si considera la gerarchia ?

PGI-Bis
28-04-2007, 13:57
Direi che isTypeOf ti da un'informazione più specifica. Dice che "o" è esattamente uno (String, Integer, Giovannone eccetera).

isKindOf racconta qualcosa di diverso. Dice che "o" come minimo è uno (String, Integer, Giovannone). Non è detto che sia esattamente uno (String, Integer, Giovannone). Potrebbe essere "istanza di un sottotipo di...".

Penso che sia giusto dire sia che isTypeOf non tiene conto della gerarchia.

misterx
28-04-2007, 14:12
però mi è parso di capire che in UML esiste solo isKindOf......

E' possibile che una superclasse veda il contenuto delle variabili sella sua sottoclasse ?

Se ho ad esempio la classe Rettangolo:
public class Rettangolo{
Integer lato = 150;
}

ed istanzio un oggetto di classe rettangolo dalla medesima classe; posso scrivere:

stampa o.lato ?
Ci vuole un cast ?

Mi è venuto questo dubbio in quanto ho isto un esempio dove una superclasse vede il contenuto delle variabili della sua sottoclasse, ma credo sia possibile solo se queste sono pubbliche.

PGI-Bis
28-04-2007, 14:41
Una superclasse non vede nè le variabili nè i metodi di una sottoclasse.

misterx
28-04-2007, 17:17
molto strano allora quanto è riportato nella figura a dx
http://img234.imageshack.us/img234/7996/snap0022pz7.th.jpg (http://img234.imageshack.us/my.php?image=snap0022pz7.jpg)

alla classe cell è celato solo il contenuto di old in quanto dichiarato privato. Forse sbaglio nel dire "vedere" e cioè che Cell vede le variabili della sottoclasse ed invece il rettangolo a dx rappresenta solo un sottoinsieme; gli oggetti di ReCell sono anche oggetti di Cell ma non il contrario.

E forse sto facendo confuzione tra java e UML

uhm....e poi la distinzione tra oggetti di tipo A e oggetti di classe implementativa...che caos

PGI-Bis
28-04-2007, 17:55
Lo schema a sinistra credo tenti di rappresentare la compatibilità tra istanze delle tre classi. Penso si possa leggere come

ogni istanza di ReCell è compatibile con ogni istanza di Cell ed ogni istanza di Cell è compatibile con ogni istanza di ReadOnlyCell.

Per "istanza di" intente quel famoso "esattamente di".

Lo schema a destra è più complicato. Credo che cerchi di significare polimorfismo ma è un atto di fiducia verso il titolo.

Comunque non darti troppi pensieri: è proprio UML che fa schifo di suo.

misterx
29-04-2007, 07:42
per quanto riguarda l'immagine sul lato sinistro la spiegazione è che: una gerarchia di classi, può essere vista in termini di sottoinsieme; un oggetto di ReCell è anche un oggetto di Cell e quindi un oggetto di ReadOnlyCell.

Detta a questo modo, va contro a quello che mi hai detto tu e cioè che in java non è possibile che una superclasse veda alcunchè di una sua sottoclasse.

Ma in termi insiemistici sembra sia tutto possibile. Forse è solo un'altra astrazione di UML per rappresentare le classi nella OOP e mostrare come cooperano tra loro, però grafici come quelli nel disegno traggono in inganno.

misterx
29-04-2007, 09:00
Non sempre. Per esempio nel caso dei tipi primitivi long è supertipo di int ma non è una superclasse di int (anzi non è neanche una classe)

intendi dire che ad esempio un tipo può essere classe oppure istanza oppure un tipo primitivo ?


public class Animale{}
Animale è un tipo classe

int Animale;
Animale è un tipo primitivo

Animale c=new Gatto();
c è un tipo istanza

PGI-Bis
29-04-2007, 09:59
Giusto per chiarire, la storia dei tipi riguarda ogni linguaggio, non solo Java o quelli orientati agli oggetti. E, per chiarire ulteriormente, dopo "tipo" ci va "di dato", ma la specificazione solitamente si omette per evidenza.

Confermo che nessun linguaggio creato, in creazione o creando potrà mai consentire ad un supertipo di conoscere comportamenti o proprietà di un suo sottotipo.

Il diagramma che mostra una superclasse come un insieme che contiene le sottoclassi è conforme alla teoria dei tipi. Cos'è un tipo? Un tipo è un sottoinsieme dell'insieme di tutti i dati computabili. Tra tutti i dati computabili, quelli che appartengono ad un certo tipo sono tutti e soli quelli a cui risulta applicabile una certa collezione di operazioni.

Se io dico che il Tipo A è l'insieme dei dati a cui è applicabile l'operazione +, prendo l'insieme dei dati computabili e lo divido in due parti: da una parte ci sono tutti i dati computabili a cui NON è applicabile l'operazione +. Dall'altra ci sono tutti i dati computabili a cui E' applicabile l'operazione +.

Se dico che il Tipo B è l'insieme dei dati a cui è applicabile l'operazione *, prendo l'insieme dei dati computabili e lo divido in due parti: da una parte ci sono tutti i dati computabili a cui NON è applicabile l'operazione *. Dall'altra ci sono tutti i dati computabili a cui E' applicabile l'operazione *.

E' possibile che alcuni dei dati appartenenti all'insieme A appartengano all'insieme B? Be', è possibile. E' una questione di intersezioni.

MA se io dico che il Tipo B è l'insieme dei dati a cui è applicabile l'operazione * E AGGIUNGO che il Tipo B è un sottotipo del Tipo A l'operazione che faccio non è più:

prendi l'insieme di tutti i dati computabili e dividilo in due...

ma

prendi tutti i dati che appartengono al Tipo A e dividilo in due: da una parte tutti i dati di Tipo A a cui NON è applicabile l'operazione *, dall'altra tutti i dati di Tipo A a cui E' applicabile l'operazione *.

E a questo punto dovrebbe apparire cristallina anche la ragione per cui un (riferimento ad un oggetto di) Tipo A non permette di osservare le operazioni che determinano il Tipo B, cioè quelle operazioni IN PIU' che un sottotipo ha rispetto al supertipo. Non può farlo perchè non tutto ciò che è di Tipo A è di Tipo B: ci sono degli A a cui non è applicabile il *. Se a tutti gli A fosse applicabile il * allora il Tipo A ed il Tipo B non sarebbero due tipi ma uno solo e, dunque, non potremmo parlare di osservabilità di un'operazione del sottotipo da parte del supertipo, mancando sia il supertipo che il sottotipo.

intendi dire che ad esempio un tipo può essere classe oppure istanza oppure un tipo primitivo ?

int è un tipo tanto quanto lo è Object, così come i primitivi sono dati tanto quanto lo sono le istanze. La differenza è, semplicemente, che esistono operazioni che puoi fare su un dato di tipo int che non puoi fare su un dato di tipo Object E viceversa. Sono insiemi disgiunti.

misterx
29-04-2007, 10:33
scusa PGI, ma la mia affermazione si legava anche al disegno che ho postato. Quel disegno va visto in considerazione della: semantica type->instance che è poi il titolo dell'oscuro argomento che sto cercando di fare mio......mannaggia 3 volte.....

Credo, che se considero quel disegno come istanze, devo fare(credo) un tipo di ragionamento, se come classi un altro tipo etc.....

Ragionando come istanze, se la superclasse fosse Figura ed avesse una sottoclasse Rettangolo e poi ancora Quadrato, potrei dire che una istanza di Quadrato è anche una istanza di Rettangolo e di Figura ?

Credo di si.

Ma potrei anche dire che una classe di Quadrato è anche una classe di Rettangolo e di Figura ?

Intuitivamente credo di no, ma non ne conosco il motivo.

Parlando di UML, ho capito che la semantica tipo->istanza va interpretata come: le classi si istanziano in oggetti e le loro associazioni(ereditarietà) tra le classi si istanziano link(che sono relazioni UML tra oggetti).

Comunque è un caos pazzesco.

PGI-Bis
29-04-2007, 10:57
Ma potrei anche dire che una classe di Quadrato è anche una classe di Rettangolo e di Figura ?

Intuitivamente credo di no, ma non ne conosco il motivo.

Be', una buona notizia comunque c'è: parlo cinese. Non lo sapevo. Lingua affascinante :D

misterx
29-04-2007, 11:03
Be', una buona notizia comunque c'è: parlo cinese. Non lo sapevo. Lingua affascinante :D

no scusa, può essere che qualcosa mi è sfuggita :muro:

misterx
29-04-2007, 11:53
no scusa, può essere che qualcosa mi è sfuggita :muro:

ma a quale punto delle tue risposte ti riferisci ? :stordita:

PGI-Bis
29-04-2007, 12:37
L'ultima, quella sugli insiemi. Vale sia per ciò che riguarda il rapporto tra le classi (gli insiemi) che il rapporto tra le istanze e le classi (i dati e gli insiemi a cui appartengono).

misterx
29-04-2007, 12:42
L'ultima, quella sugli insiemi. Vale sia per ciò che riguarda il rapporto tra le classi (gli insiemi) che il rapporto tra le istanze e le classi (i dati e gli insiemi a cui appartengono).

ah, ok.
Tieni presente che sto mescolando java e UML, ecco il motivo della confusione :muro:

misterx
29-04-2007, 12:52
aspetta PGI, forse....

Nel caso della figura con polimorfismo a dx, vuol solo fare intendere che la classe Cell è in grado di istanziare sia oggetti della sua classe che della sua sottoclasse e poi, in base alla firma della classe che ha generato l'oggetto, a run-time verrà usato il metodo corretto, anche se questo è presente nella classe Cell.
La figura depista parecchio :muro:
Nel caso poi di istanze di Cell parliamo di tipo isKindOf(tipo più generico), in quanto qui c'è di mezzo la generalizzazione; mentre nel caso di istanze di una classe senza alcuna generalizzazione parliamo di istanze tipo isTypeOf(tipo più specifico).

misterx
30-04-2007, 15:54
come si implementa la relazione di associazione tra classi in java ?

La generalizzazione attraverso l'ereditarietà, la realizzazione attraverso le interfacce ma l'associazione ?

help :muro:

misterx
01-05-2007, 08:00
ho trovato, grazie lo stesso