Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    22

    Come usare l'ereditarietà e il poliformismo

    Salve ragazzi e auguri di buon natale passati.
    Vorrei trovare una soluzione sull'implementazione di due classi, certamente questo problema dipende da un a lacuna sull'ereditarietà e poliformismo che ho, credetemi e da stamattina che li studiando, ma non sono riuscito a trovare una soluzione.
    Il punto è questo, faccio un esempio: ho una classe prodotto che contiene due proprità (prezzo netto e prezzo ivato), per cercare di capire e iniziare ad utilizzare l'usabilità del codice, ho pensato di creare una classe CalcolaPrezzi che eridita la classe Prodotto (forse in questo contesto non è il caso di usare l'ereditarietà ma potrei direttamente creare i metodi di calcolo all'interno della classe Prodotto), che ha i metodi oppurtuni per calcolare i prezzi.
    Il procedimento è questo: creo l'istanza Prodotto, assegno dei valori ai prezzi, cambio l'importo es. prezzo netto, automaticamente dovrei cambiare l'importo prezzo Ivato o viceversa, tramite la classe CalcoloPrezzi. Il problema è che non riesco ad assegnare il riferimento della classe Prodotto all'istanza CalcolaPrezzi. Cerco di postare l'esempio con del codice:
    codice:
    Prodotto.java
    
    public class Prodotto{
    
    	private int codice;
    	private double prezzoNetto;
    	private double prezzoIvato;
    
    	public Prodotto(in codice, double prezzoNetto, double prezzoIvato){
    		this.codice = codice;
    		this.prezzoNetto = prezzoNetto;
    		this.prezzoIvato = prezzoIvato;
    	}
    
    	public void setPrezzoNetto(double prezzoNetto){
    		this.prezzoNetto = prezzoNetto;
    	}		
    	public double getPrezzoNetto(){
    		return prezzoNetto();
    	}
    
    	public void setPrezzoIvato(double prezzoIvato){
    		this.prezzoIvato = prezzoIvato;
    	}	
    	public double getPrezzoIvato(){
    		return prezzoInvato;
    	}
    }
    
    CalcolaPrezzi.java
    
    public class CalcolaPrezzi extends Prodotto{
    
    	private double netto;
    	private double ivato;
    	
    	public double calcolaprezzoIvato(){
    		ivato = super.getPrezzoNetto + 21%;
    		return ivato;
    	}
    	
    	public double calcolaPrezzoNetto(){
    		netto = super.getPrezzoIvato - 21%;
    		return netto;
    	}
    }
    
    GestioneProdotto.java
    
    public class GestioneProdotto{
    	public static void main(String args[]){
    	
    		Prodotto prodotto = new Prodotto(1, 321,00, 388,41);
    		System.out.println("Netto="+prodotto.getPrezzoNetto);
    		System.out.println("Ivato="+prodotto.getPrezzoIvato);
    		
    		prodotto.setPrezzoNetto(367,00);
    		
    		/* Come posso assegnare il riferimento dell'oggetto Prodotto a CalcolaPrezzi? 
    		* e qui che mi perdo.
    		*/
    
    		/* ho provato con questo codice ma non va */
    		CalcolaPrezzi calcola = new CalcolaPrezzi();
    		prodotto = calcola;
    		System.out.println("Ivato="+prodotto.calcolaPrezzoIvato());  // restiuisce zero
    		
    		// oppure con questo, ma è sempre uguale
    		
    		Prodotto calcola = new CalcolaPrezzi();
    		System.out.println("Ivato="+prodotto.calcolaPrezzoIvato());  // restiuisce zero
    		
    	}
    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    prima osservazione: cosa c'entra CalcolaPrezzi con Prodotto?
    L'ereditarietà (che è la prima cosa che non usi bene) si basa sull'estendere un concetto esistente, non sullo stravolgerlo.
    Mi aspetto che da Prodotti tu derivi Libri, Tavoli, Sedie....non operazioni matematiche!!!!
    RTFM Read That F*** Manual!!!

  3. #3
    Secondo me qui non devi assolutamente usare l'ereditarietà. Non c'entra nulla in questo caso.
    Come dice valia, da Prodotto, puoi creare altre sottoclassi Libro, Tavolo, ecc. che sono delle specializzazioni di prodotto, che hanno le stesse proprietà di Prodotto, ereditate da esso, ma ne hanno anche altre, caratteristiche di ciascuna generalizzazione, ovvero di Libro, tavolo ecc.

    Mi rendo conto che nella tua mente alberghi una confusione terribile, quindi è complicato anche capire cosa vuoi fare, ma il punto è che sbagli nell'applicare l'ereditarietà.

    Ti faccio un esempio pratico:

    codice:
    Prodotto.java
    
    public class Prodotto{
    
    	private int codice;
    	private double prezzoNetto;
    	private double prezzoIvato;
    
    	public Prodotto(int codice, double prezzoNetto, double prezzoIvato){
    		this.codice = codice;
    		this.prezzoNetto = prezzoNetto;
    		this.prezzoIvato = prezzoIvato;
    	}
    
    	public void setPrezzoNetto(double prezzoNetto){
    		this.prezzoNetto = prezzoNetto;
    	}		
    	public double getPrezzoNetto(){
    		return prezzoNetto();
    	}
    
    	public void setPrezzoIvato(double prezzoIvato){
    		this.prezzoIvato = prezzoIvato;
    	}	
    	public double getPrezzoIvato(){
    		return prezzoInvato;
    	}
    }
    
    
    Tavolo.java
    
    public class Tavolo extends Prodotto {
    
    	private int zampe;
    	private String colore;
    	public Tavolo(int codice, double prezzoNetto, double prezzoIvato, int zampe, String colore){
    		super(codice,prezzoNetto,prezzoIvato);
    		this.zampe = zampe;
    		this.colore = colore;
    	}
    	
    	public void setZampe(int z){
    		zampe = z;
    	}
    	
    	public int getZampe(){
    		return zampe;
    	}
    	
    	public void setColore(String c){
    		colore = c;
    	}
    	
    	public String getColore(){
    		return colore;
    	}
    }
    
    
    Main.java
    
    public class Main{
    	public static void main(String[] args){
    		Tavolo t = new Tavolo(1,10,12.1,4,"nero");
    		System.out.println(t.getPrezzoNetto());
    		t.setColore("giallo");
    		System.out.println(t.getColore());
    	}
    }
    Come vedi l'oggetto Tavolo è a tutti gli effetti anche un oggetto Prodotto e come tale può usare i metodi della classe Prodotto, ma ne ha anche altri.

    Ciao!

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    22
    Grazie per la vostra tempestiva risposta, come ho già precisato in questo caso non c'è necessità di usare l'ereditarietà, dato che calcolaprezzi può essere un metodo di Prodotto e non una classe derivata, giustamente messo cosi l'esempio fa pensare un errato uso di ereditarietà, sicuramente non sono riuscito a spiegare bene i miei dubbi su questo argomento. Prendiamo l'esempio di fbcyborg, e vorrei aggiungere a Tavolo un metodoto che deve calcolare un amento del prezzo fisso, stessa cosa vale per le altre classi derivate(Sedia, Sgabello) ogni una con un suo aumento del prezzo fisso, non è possibile fare ciò:
    codice:
    Main.java
    
    public class Main{
    	public static void main(String[] args){
    	
    		Prodotto prodotto = new Prodotto(1, 321,00);
    		System.out.println("Netto="+prodotto.getPrezzo);
    		
    		prodotto.setPrezzo(367,00);
    		
    		/* Come posso assegnare il riferimento dell'oggetto Prodotto a Tavolo? 
    		* e qui che mi perdo.
    		*/
    
    		Tavolo tavolo = new Tavolo();
    		prodotto = tavolo;
    		System.out.println("Prezzo definitivo="+prodotto.calcolaPrezzo());
    	}
    }

  5. #5
    Non lo puoi fare.

    Un'istanza di Tavolo è un'istanza di Prodotto ma non viceversa.

    non capisco perché vuoi fare questa cosa:
    codice:
    prodotto = tavolo;
    Non ha senso scusa.
    Io credo che tu voglia fare qualcosa che sicuramente si può fare e si fa in altro modo.

    Sicuramente sono io che non capisco bene le tue esigenze, quindi ti chiedo di spiegarmi a parole qual'è il tuo obbiettivo. Capire come funziona l'ereditarietà o realizzare qualcos'altro?

  6. #6
    Allora ho fatto qualche prova con il codice. Seguendo quello che dici tu, ovvero:

    vorrei aggiungere a Tavolo un metodoto che deve calcolare un amento del prezzo fisso
    OK, aggiungiamo a Tavolo questo metodo:

    Tavolo.java:
    codice:
    public class Tavolo extends Prodotto {
    	private int zampe;
    	private String colore;
    	public Tavolo(int codice, double prezzoNetto, double prezzoIvato, int zampe, String colore){
    		super(codice,prezzoNetto,prezzoIvato);
    		this.zampe = zampe;
    		this.colore = colore;
    	}
    	
    	public void setZampe(int z){
    		zampe = z;
    	}
    	
    	public int getZampe(){
    		return zampe;
    	}
    	
    	public void setColore(String c){
    		colore = c;
    	}
    	
    	public String getColore(){
    		return colore;
    	}
    	
    	public double calcolaPrezzoAumentato(){
    		return this.getPrezzoIvato()+100;
    	}
    }
    Il metodo calcolaPrezzoAumentato(), me lo sono inventato così...

    Bene, ora la classe Main.java:
    codice:
    public class Main {
    	public static void main(String[] args){
    		Prodotto prodotto = new Prodotto(1, 321, 330);
    		System.out.println("Netto="+prodotto.getPrezzoNetto());
    		
    		prodotto.setPrezzoNetto(321);
    		
    		/* Come posso assegnare il riferimento dell'oggetto Prodotto a Tavolo? 
    		* e qui che mi perdo.
    		*/
    
    		Tavolo tavolo = new Tavolo(1, 321, 330,4,"giallo");
    		prodotto = tavolo;
    		System.out.println("Prezzo definitivo="+prodotto.calcolaPrezzoAumentato());
    	}
    }
    Ecco: prodotto.calcolaPrezzoAumentato() non puoi farlo.
    Prodotto non ha metodi con quella segnatura. Inoltre, se tu fai prodotto=tavolo, tagli le gambe al tavolo!!!
    Nel senso: incasini l'oggetto prodotto che ora punta a tavolo, ma è di tipo prodotto.
    Non so se si capisce ora.

    La classe Prodotto è rimasta invariata.

    Comunque:
    stessa cosa vale per le altre classi derivate(Sedia, Sgabello) ogni una con un suo aumento del prezzo fisso, non è possibile fare ciò
    la soluzione a questo problema potrebbe essere la seguente:
    1) definisci un metodo calcolaPrezzoAumentato() in Prodotto
    2) per ogni classe che estende Prodotto, ridefinisci calcolaPrezzoAumentato() (perché per ogni sottoclasse il prezzo aumenta diversamente)
    A questo punto non ti serve più fare prodotto=tavolo, e puoi semplicemente invocare calcolaPrezzoAumentato() su tavolo.

    Oppure senza che ridefinisci quel metodo, lo implementi solo nelle sottoclassi come al punto 2.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    22

    Come usare l'ereditarietà e il polimorfismo

    Pensavo fosse possibile assegnare un riferimento della classe derivata alla classe base e di conseguenza ereditava anche i valori assegnati nel riferimento della classe base. Con il tuo esempio credo di aver capito che devo istanziare un oggetto della classe derivata che a sua volta con il costruttore crea il riferimento alla classe base, poi magari è possibile fare il polimorfismo(che non serve, ma penso sia possibile fare) cioè assegnando alla classe base il riferimento della classe derivata dato che Tavolo è sicuramente(is-a) Prodotto.

  8. #8
    Il consiglio che ti do, è di non fare mai questo tipo di assegnazioni.
    Devi sempre tenere a mente questa cosa: se dichiaro Tavolo t, t è un'istanza della classe Tavolo, ma allo stesso tempo è anche un'istanza della classe Prodotto e non viceversa. Quindi su t puoi invocare tutti i metodi della classe Prodotto + tutti i metodi della classe Tavolo. Al contrario da un oggetto p di Prodotto, non puoi invocare i metodi della classe Tavolo. Da ciò, penso tu possa fare tutte le deduzioni del caso, senza che ti faccio altri esempi!


  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    22
    I tuoi esempi sono stati di grande aiuto, vedo che sei molto preparato. Credo di aver affrontato bene oggi il discorso dell'ereditarietà visto che è uno degli argomento fondamentali della OOP, cercherò di esercitarmi meglio studiando.

    Posso fare una domanda fuori da questa sezione? ma è possibile aumentare il time-out della sessione al forum, quando si scrive un thread, perché mi sembra troppo poco.

    Grazie infinitamente e auguri di buon anno.

  10. #10
    Grazie! Ho studiato per molti anni :P
    Poi qualche imprecisione potrei commetterla anche io ovviamente! però ciò che ti ho scritto è corretto

    Per l'altra richiesta, ti conviene contattare in privato un moderatore, comunque, io non ho di questi problemi sinceramente.

    Buon anno anche a te!

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.