Corso base Java: bisogno di aiuto

di il
23 risposte

Corso base Java: bisogno di aiuto

Salve,
ho iniziato da due giorni un corso di formazione incentrato sulla OOP con Java come linguaggio di programmazione da approfondire.
Purtroppo ho iniziato ad avere difficoltà sin dal primo giorno, ma ci terrei tanto ad imparare (o quantomeno ad avere un'idea di base) a programmare usando Java. Mi servirebbero delle delucidazioni.

Il concetto di classe e sottoclasse mi è abbastanza chiaro. Qui dobbiamo da una classe figure geometriche creare le sottoclassi rettangolo e quadrato, calcolare area e perimetro delle due figure geometriche, quindi poi stampare area, perimetro, e tutte le info su ogni singola figura.

Avevo pensato intanto di creare la classe FiguraGeometriche con all'interno il metodo main, poi di creare la classe rettangolo extends FigureGeometriche, dichiarare gli attributi private (mi confermate che gli attributi vanno sempre dichiarati come privati?), (due double) base ed altezza, quindi dichiaro il costruttore, poi il metodo "area" con valori di ritorno base * altezza. Infine il tostring per andare poi a stampare tutto il necessario.

A questo punto dalla classe FiguraGeometriche creo l'oggetto rettangolo che è una istanza della classe rettangolo, invoco il metodo area e poi stampo tutto.

Immagino di commettere diversi errori... perché non mi stampa l'area? perché non mi stampa r1 ed r2 ma "rettangolo"?

grazie mille, so che sono stupidaggini ma da qualche parte devo partire...

package Primo;

public class Rettangolo extends FigGeo{

private double base;
private double altezza;

public Rettangolo(int base, int altezza) {
this.base = base;
this.altezza = altezza;
}

double area() {
return base*altezza;
}

@Override
public String toString() {
return "Rettangolo [base=" + base + ", altezza=" + altezza + "]";
}
}



package Primo;

public class FigGeo {

public static void main(String[] args) {

Rettangolo r1 = new Rettangolo(5.5, 10.0);
r1.area();
System.out.println(r1);


Rettangolo r2 = new Rettangolo(2.5, 5.0);
r2.area();
System.out.println(r2);

}
}

23 Risposte

  • Re: Corso base Java: bisogno di aiuto

    Scusate , credo d'aver capito l'errore... ci stavo sbattendo la testa da 1 ora e ci sono arrivato 5min dopo aver scritto il post.. quando invocavo il tostring bisognava inserire anche il metodo area e non solo gli attributi.. giusto?

    Resta però l'altro problema.. perché mi stampa
    Rettangolo [base=5, altezza=10, area()=50]
    Rettangolo [base=2, altezza=5, area()=10]

    e non r1 anziché Rettangolo...
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Qui dobbiamo da una classe figure geometriche creare le sottoclassi rettangolo e quadrato, calcolare area e perimetro delle due figure geometriche, quindi poi stampare area, perimetro, e tutte le info su ogni singola figura.
    Un "classico".

    WinstonSmith ha scritto:


    Avevo pensato intanto di creare la classe FiguraGeometriche con all'interno il metodo main, poi di creare la classe rettangolo extends FigureGeometriche
    Sarebbe meglio se separi la super-classe dal main di "prova". Ovvero es.:
    - classe EsercizioFigureGeometriche (con il solo main() di prova più eventuali metodi ai fini della prova)
    - classe FiguraGeometrica
    - classi Rettangolo, Quadrato, ....

    WinstonSmith ha scritto:


    mi confermate che gli attributi vanno sempre dichiarati come privati?
    Per una "buona" programmazione object-oriented, sì.
    Raramente protected e possibilmente mai public.

    WinstonSmith ha scritto:


    (due double) base ed altezza, quindi dichiaro il costruttore, poi il metodo "area" con valori di ritorno base * altezza. Infine il tostring per andare poi a stampare tutto il necessario.
    Sì, grosso modo ok. Ma c'è una questione importante. La classe che ho detto prima, FiguraGeometrica, cioè la superclasse di Rettangolo ecc... avrebbe senso innanzitutto che sia abstract (non istanziabile, non ha senso fare new FiguraGeometrica() ) e poi che abbia i 2 metodi abstract per area e perimetro. Così innanzitutto è un obbligo implementarli nelle sottoclassi e poi così già a livello di superclasse è "noto" il concetto di calcolo di area e perimetro.

    Rivedi il tuo codice in base a quanto detto.
  • Re: Corso base Java: bisogno di aiuto

    andbin ha scritto:


    ...
    Intanto grazie per le varie informazioni. Devo andarmi a vedere il concetto di classe abstract, nei due giorni di corso non ne abbiamo parlato.

    Purtroppo in questo corso, nonostante sia stata fatta una selezione che includeva una chiacchierata sulla preparazione "tecnica" del candidato dove sono venuti fuori tutti i miei limiti e la mia ignoranza in materia, mi sembra si stiano dando un po' troppe cose per scontate.

    Ad esempio, oltre alle cose già dette bisogna anche andare a stampare la somma dei due perimetri dei due rettangoli, dei due quadrati e la somma quindi dei 4 perimetri.

    Ma queste operazioni in quale classe vanno svolte e perché?
    Ora, la somma dei Perimetri dei due rettangoli sarà uguale a al perimetro del primo + quello del secondo, quindi si crea un metodo per calcolare la somma che abbia come ritorno r1.perimetro + r2.perimetro o sono completamente fuori strada?

    Quando ho chiesto al prof mi ha detto di "provare" e "riprovare" , ma a me servirebbe intanto capire come ci si muove...

    Poi bisognerebbe creare un array di figure, comrpendente rettangolo, quadrato e triangolo e che a seconda dell'elemento "pescato" vada a calcolare area e perimetro. Qui non vi chiedo neanche di provare a correggermi perché mi son perso già alla voce precedente, ma immagino si debba dichiarare una classe enum con variabili appunto rettangolo, quadrato e triangolo, assegnare un valore a queste tre (ad es 0, 1, 2). Usare il ciclo for, al primo giro indice 0, mi va a calcolare area e perimetro del rettangolo e cosi via, tutto questo grazie allo switch. Quanto sono lontano?
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Devo andarmi a vedere il concetto di classe abstract, nei due giorni di corso non ne abbiamo parlato.
    Capisco. La superclasse FiguraGeometrica puoi anche farla non abstract per il momento (se non abstract, non puoi metterci dentro metodi abstract). Anzi, potrebbe anche non servirti. Una superclasse del genere serve quando si vuole "astrarre" il concetto di figura geometrica in modo tale da poter trattare in maniera uniforme più oggetti specifici. Ad esempio poter avere un array FiguraGeometrica[] o collezione List<FiguraGeometrica> che possono contenere qualunque oggetto sottotipo di FiguraGeometrica. O se devi fare metodi che devono operare stando sul concetto generalizzato di FiguraGeometrica e non di un tipo specifico.

    WinstonSmith ha scritto:


    Quando ho chiesto al prof mi ha detto di "provare" e "riprovare" , ma a me servirebbe intanto capire come ci si muove...
    Fai la classe Rettangolo che sia così:
    - campi base/altezza come private
    - costruttore public che riceve i dati da assegnare subito ai campi
    - eventuali metodi getter/setter public (se necessari)
    - metodi per area/perimetro:
    public double area() { ..... }
    public double perimetro() { ..... }
    - toString() che fornisce la stringa con il formato che vuoi (come stavi facendo è ok)

    Similare per un Quadrato (avrà solo campo "lato").

    Poi nel main() crei degli oggetti di prova, invochi i metodi che ti servono (es. area su 2 oggetti Rettangolo), stampi i risultati ecc...

    Nota che fare una istruzione solo così:
    r1.area();

    non serve a niente. area() non stampa nulla, restituisce solo un valore. E non assegnandolo/passandolo altrove, appunto è inutile.
  • Re: Corso base Java: bisogno di aiuto

    Ti ringrazio, ho capito un po' di cose che non mi erano chiare, corretto errori, e sono riuscito a concludere la prima parte.
    Mentre su cosa fare per stampare area e perimetro a seconda della figura "pescata" non ci sono arrivato, anche se ho fatto diverse prove. Mi viene solo da pensare ad un for su un array di indice 3, con l'indice 0 associato al rettangolo, indice 1 al quadrato ed indice 2 al triangolo, e con lo switch andare ad eseguire quei metodi su quella figura, ma niente da fare..
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Mentre su cosa fare per stampare area e perimetro a seconda della figura "pescata" non ci sono arrivato, anche se ho fatto diverse prove. Mi viene solo da pensare ad un for su un array di indice 3, con l'indice 0 associato al rettangolo, indice 1 al quadrato ed indice 2 al triangolo, e con lo switch andare ad eseguire quei metodi su quella figura, ma niente da fare..
    No, nessun switch. Una superclasse come FiguraGeometrica (possibilmente abstract, perché non ha senso che sia "concreta" e con i 2 metodi area() e perimetro() abstract) serve proprio a quello, per "accomunare" le varie implementazioni possibili.
    Se avessi un array FiguraGeometrica[] di 3 elementi con dentro 1 Rettangolo, 1 Quadrato, 1 Triangolo, non ti interesserebbe "vedere" il tipo specifico, ma solo sapere che FiguraGeometrica ha area() e perimetro(). E ciascun sotto-tipo ha la ridefinizione corretta che sarebbe invocato "polimorficamente".
  • Re: Corso base Java: bisogno di aiuto

    Ma quindi una cosa scritta così è completamente sbagliata anche se mi dà la soluzione?

    package Primo;

    public abstract class EsercizioFiguraGeometrica {

    public static void main(String[] args) {
    int sommaAr; //somma area rettangoli
    int sommaAq; //somma area quadrati
    int somma; //somma di area e perimetro di tutte le figure

    Rettangolo r1 = new Rettangolo(5,10);
    Rettangolo r2 = new Rettangolo(2,5);
    System.out.println(r1);
    System.out.println(r2);

    sommaAr = r1.area()+r2.area();
    System.out.println("la somma dell'area dei due rettangoli é: " + sommaAr + "cm");

    Quadrato q1 = new Quadrato (5);
    Quadrato q2 = new Quadrato (3);
    System.out.println(q1);
    System.out.println(q2);

    sommaAq = q1.area()+q2.area();
    System.out.println("la somma dell'area dei due quadrati é: " + sommaAq + "cm");

    somma= r1.area()+r2.area()+r1.perimetro()+r2.perimetro()+q1.area()+q1.perimetro()+q2.area()+q2.perimetro();
    System.out.println("il totale é: " + somma + "cm");
    }
    }




    Rettangolo [base=5, altezza=10, area()=50, perimetro()=30]
    Rettangolo [base=2, altezza=5, area()=10, perimetro()=14]
    la somma dell'area dei due rettangoli é: 60cm
    Quadrato [lato=5, area()=25, perimetro()=20]
    Quadrato [lato=3, area()=9, perimetro()=12]
    la somma dell'area dei due quadrati é: 34cm
    il totale é: 170cm



    grazie ancora.
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Ma quindi una cosa scritta così è completamente sbagliata anche se mi dà la soluzione?
    Dal punto di vista dell'uso degli oggetti, è tutto corretto. Finché hai variabili distinte e dello stesso tipo degli oggetti che crei, il "polimorfismo" non c'entra.
    E devi chiaramente invocare area() e perimetro() esplicitamente e "direttamente" tu su ciascun oggetto.

    È invece sbagliato (non ha senso) sommare aree con perimetri (sommi patate con banane ... ).

    Ma prova invece con un array che contiene figure di vari tipi (ti serve un super-tipo comune). E prova la somma di aree dall'array.
  • Re: Corso base Java: bisogno di aiuto

    Sì, la somma di area e perimetro l'ho fatta giusto per capirci qualcosa su come bisogna muoversi, pensavo bisognasse scrivere qualcosa di diverso anziché quel "somma=r1.area()ecc", di molto più sintetico.

    Con l'array ho fatto diverse prove, ma credo di non averci capito nulla su come far partire l'operazione. Oggi ho chiesto al prof di ritornare sull'argomento, ma niente.
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Con l'array ho fatto diverse prove, ma credo di non averci capito nulla su come far partire l'operazione. Oggi ho chiesto al prof di ritornare sull'argomento, ma niente.
    Devi avere innanzitutto un "supertipo". Chiamiamolo es. FiguraGeometrica (da cui derivano Rettangolo, ecc...):
    FiguraGeometrica[] figure = { new Rettangolo(5,10), new Quadrato(5), new Rettangolo(2,5) };
    Fai un ciclo for ("for-each" di Java 5+, se lo conosci, o il classico ciclo for per indice) sull'array. Poi somma in una variabile double areaTot tutte le aree.
    Cosa ti viene in mente? area() di quale tipo dovrebbe essere?
  • Re: Corso base Java: bisogno di aiuto

    Non è che si sia andati tanto avanti in queste tre settimane, poi spesso mi sembra che il prof dia per scontate tante cose, adesso ho dei problemi con quest'esercizio:
    In pratica bisogna dare la "traduzione letterale" di un numero. Il numero potrà andare da zero a novemilanovecentonovantanove.
    Codice a parte, avevo pensato di andare a creare 4 metodi, uno per tradurre le unità, uno per le decine, uno per le centinaia ed uno per le migliaia.
    Quindi di andare ad analizzare singolarmente ogni cifra del numero da tradurre. Oltre a chiedervi se è giusto il mio ragionamento, vorrei sapere : con le stringhe c'è il substring, ma con gli interi? Grazie.
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    In pratica bisogna dare la "traduzione letterale" di un numero. Il numero potrà andare da zero a novemilanovecentonovantanove.
    Codice a parte, avevo pensato di andare a creare 4 metodi, uno per tradurre le unità, uno per le decine, uno per le centinaia ed uno per le migliaia.
    No, non è sufficiente fare 4 metodi separati dove ognuno conosce solo una cifra e basta.
    Ci sono molti casi "particolari", prova a scrivere su un foglio (o al pc) i numeri in lettere da 0 a 100.
    Non è difficilissimo ma devi avere chiara la visione di tutti i casi particolari.

    WinstonSmith ha scritto:


    con le stringhe c'è il substring, ma con gli interi?
    Devi fare divisioni e moduli (gli operatori / e % ) in cascata fino a spezzare tutte le cifre.

    Es. 2345

    2345 / 1000 = 2
    2345 % 1000 = 345

    345 / 100 = 3
    ......

    A tua scelta puoi anche partire dal "basso":

    2345 % 10 = 5
    2345 / 10 = 234

    234 % 10 = 4
    234 / 10 = 23

    23 % 10 = ....
    .....
  • Re: Corso base Java: bisogno di aiuto

    andbin ha scritto:


    ....
    Intanto grazie ancora per la gentilezza e per la disponibilità.
    Ho provato a basarmi sul resto e sulla divisione, ma credo d'essere lontanissimo dalla soluzione ideale... funziona (a parte per i numeri che terminano con 1 ed 8, cosa che devo ancora sistemare), ma è venuto fuori una quantità spropositata di righe...
    public class Operazioni { 
    	int a;
    	int b;
    	int c;
    	int d;
    	int e;
    	int f;
    
    	public Operazioni(int a) {
    		this.a = a;
    	}
    
    	public String primacifra(int a) {
    		if(a/100000==9) {
    			return "novecento";}
    		if(a/100000==8) {
    			return "ottocento";}
    		if(a/100000==7) {
    			return "settecento";}
    		if(a/100000==6) {
    			return "seicento";}
    		if(a/100000==5) {
    			return "cinquecento";}
    		if(a/100000==4) {
    			return "quattrocento";}
    		if(a/100000==3) {
    			return "trecento";}
    		if(a/100000==2) {
    			return "duecento";}
    		if(a/100000==1) {
    			return "cento";}
    		if(a/100000==0) {
    			return "";}
    		return "";
    		}
    	
    	public String secondacifra(int a) {
    		b=a%100000;
    		if(b/10000==9) {
    			return "novanta";}
    		if(b/10000==8) {
    			return "ottanta";}
    		if(b/10000==7) {
    			return "settanta";}
    		if(b/10000==6) {
    			return "sessanta";}
    		if(b/10000==5) {
    			return "cinquanta";}
    		if(b/10000==4) {
    			return "quaranta";}
    		if(b/10000==3) {
    			return "trenta";}
    		if(b/10000==2) {
    			return "venti";}
    		if(b/10000==1) {
    			return "";}
    		if(a/100000==0) {
    			return "";}
    		return "";
    		}
    	
    	
    public String terzacifra(int a) {
    	b=a%100000;
    	c=b%10000;
    	if (b/10000==1 && c/1000==0) {
    		return "diecimila";}
    	if (b/10000==1 && c/1000==9) {
    		return "diciannovemila";}
    	if(b/10000==1 && c/1000==8) {
    	return "diciottomila";}
    	if(b/10000==1 && c/1000==7) {
    		return "diciassettemila";}
    	if(b/10000==1 && c/1000==6) {
    		return "sedicimila";}
    	if(b/10000==1 && c/1000==5) {
    		return "quindicimila";}
    	if(b/10000==1 && c/1000==4) {
    		return "quattordicimila";}
    	if(b/10000==1 && c/1000==3) {
    		return "tredicimila";}
    	if(b/10000==1 && c/1000==2) {
    		return "dodicimila";}	
    	if(b/10000==1 && c/1000==1) {
    		return "undicimila";}
    else if(c/1000==9) {
    	return "novemila";}	
    if(c/1000==8) {
    	return "ottomila";}
    if(c/1000==7) {
    	return "settemila";}
    if(c/1000==6) {
    	return "seimila";}	
    if(c/1000==5) {
    	return "cinquemila";}
    if(c/1000==4) {
    	return "quattromila";}
    if(c/1000==3) {
    	return "tremila";}	
    if(c/1000==2) {
    	return "duemila";}
    if(c/1000==1) {
    	return "mille";}
    if(a>=1001 && c/1000==0) {
    	return "mila";}
    if(a<1000 && c/1000==0) {
      return "";}
    return "";}
    
    public String quartacifra(int a) {
    	b=a%100000;
    	c=b%10000;
    	d=c%1000;
    if(d/100==9) {
    		return "novecento";}
    if(d/100==8) {
    		return "ottocento";}
    if(d/100==7) {
    		return "settecento";}
    if(d/100==6) {
    		return "seicento";}
    if(d/100==5) {
    		return "cinquecento";}
    if(d/100==4) {
    		return "quattrocento";}
    if(d/100==3) {
    		return "trecento";}
    if(d/100==2) {
    		return "duecento";}
    if(d/100==1) {
    		return "cento";}	
    if(d/100==0) {
    		return "";}
    	return "";
    	}
    	
    public String quintacifra(int a) {
    	b=a%100000;
    	c=b%10000;
    	d=c%1000;
    	e=d%100;
    if(e/10==9) {
    		return "novanta";}
    if(e/10==9) {
    	return "novanta";}
    if(e/10==8) {
    		return "ottanta";}
    if(e/10==7) {
    		return "settanta";}
    if(e/10==6) {
    		return "sessanta";}
    if(e/10==5) {
    		return "cinquanta";}
    if(e/10==4) {
    		return "quaranta";}
    if(e/10==3) {
    		return "trenta";}
    if(e/10==2) {
    		return "venti";}
    if(e/10==1) {
    	return "";}
    if(e/10==0) {
    		return "";}
    return "";
    	}
    
    public String sestacifra(int a) {
    	b=a%100000;
    	c=b%10000;
    	d=c%1000;
    	e=d%100;
    	f=e%10;
    	if(e/10==1 && f/1==0) {
    		return "dieci";}
    	if (e/10==1 && f/1==9) {
    		return "diciannove";}
    	if(e/10==1 && f/1==8) {
    	return "diciotto";}
    	if(e/10==1 && f/1==7) {
    		return "diciassette";}
    	if(e/10==1 && f/1==6) {
    		return "sedici";}
    	if(e/10==1 && f/1==5) {
    		return "quindici";}
    	if(e/10==1 && f/1==4) {
    		return "quattordici";}
    	if(e/10==1 && f/1==3) {
    		return "tredici";}
    	if(e/10==1 && f/1==2) {
    		return "dodici";}	
    	if(e/10==1 && f/1==1) {
    		return "undici";}
    	else {
    if(f/1==9 ) {
    		return "nove";}
    if(f/1==8) {
    	return "otto";}
    if(f/1==7) {
    		return "sette";}
    if(f/1==6) {
    		return "sei";}
    if(f/1==5) {
    		return "cinque";}
    if(f/1==4) {
    		return "quattro";}
    if(f/1==3) {
    		return "tre";}
    if(f/1==2) {
    		return "due";}	
    if(f/1==1) {
    		return "uno";}
    if(f/10==0) {
    		return "";}
    return "";
    	}}
    } 
    Nella classe dove eseguo le operazioni dò un numero e -creato l'oggetto x- stampo x.primonumero(a) + x.secondonumero(a) ecc
    A parte tutti gli errori ed il fatto d'aver scritto troppo, mi chiedevo se ad esempio a questo punto fosse possibile eliminare le centinaia visto che il "novecento" di novecentomila è lo stesso di novecento(900). Ho fatto alcuni tentativi, ma non ne sono venuto a capo.
  • Re: Corso base Java: bisogno di aiuto

    WinstonSmith ha scritto:


    Ho provato a basarmi sul resto e sulla divisione, ma credo d'essere lontanissimo dalla soluzione ideale...
    No, mi spiace. Quello che hai scritto non ha assolutamente alcun senso.

    Innanzitutto NON devi fare tonnellate di divisioni/moduli per qualunque cosa. Hai un numero di 4 cifre, quindi ti basta fare quelle poche operazioni per ottenere 4 int separati con ciascuno il numero 0...9. E per farlo puoi anche fare una cosa "furba", un metodo ad esempio da usare come:

    int migliaia = estraiDigit(numero, 1000);
    int centinaia = estraiDigit(numero, 100);
    ...

    Dove estraiDigit è un banalissimo metodo con 1 (UNA!) riga di codice dentro. Stop, tutto lì e hai i 4 digit. (p.s. puoi anche evitare il estraiDigit e fare tutto lì "in linea".. era solo per farti ragionare)

    Poi l'ho detto prima: hai scritto e/o analizzato un po' di casi? Le migliaia e le centinaia sono abbastanza lineari e possono essere trattati singolarmente per il loro pezzetto di stringa. Molti dei casi particolari sono invece nei valori 0...99.

    I primi 20 valori (0..19) sono i casi molto "particolari" (e i primi 10 da 0 a 9 li dovrai RI-utilizzare sovente!!), li si mette generalmente in un array:

    String[] primiVenti = { "zero", "uno", ......... };

    Se i due digit "bassi" rappresentano un valore tra 0 e 19, banalmente si "indirizza" nell'array e stop.

    Poi hai analizzato il resto?

    venti
    ventuno
    ventidue
    ventitre
    ventiquattro
    venticinque
    ventisei
    ventisette
    ventotto
    ventinove

    Se noti, ventuno e ventotto sono gli unici a NON avere la "i" di venti. E se ragioni/provi, una cosa analoga c'è per tutti i valori 3x, 4x, 5x, 6x, 7x, 8x e 9x. Quindi cosa ti potrebbe far pensare? Magari di fare un array in cui ci sono le decine senza la finale:

    String[] decine = { "", "", "vent", "trent", ..... };

    La decina 2x è l'unica con la "i" finale. Le altre hanno la "a" finale. Metti la decina troncata e metti la finale ma solo se l'unità non è 1 o 8. E infine aggiungi la stringa dell'unità ma solo se non è 0 (da quell'array primiVenti).

    E continui i ragionamenti così. E arriverai ad un codice che è MOLTO più corto e migliore di quello che hai scritto.


    EDIT: e anzi, magari eventualmente 2 array per le decine, uno senza finali e l'altro con finali. Evita perlomeno il test per il caso 2x "i" vs "a".
Devi accedere o registrarti per scrivere nel forum
23 risposte