Polimorfismo vs Override vs Overloading


347

In termini di Java, quando qualcuno chiede:

che cos'è il polimorfismo?

Il sovraccarico o l' override sarebbe una risposta accettabile?

Penso che ci sia qualcosa di più.

SE tu avessi una classe base astratta che ha definito un metodo senza implementazione e hai definito quel metodo nella sottoclasse, è ancora prioritario?

Penso che il sovraccarico non sia sicuramente la risposta giusta.


Di seguito le risposte spiegano molto bene il polimorfismo. Ma ho una forte obiezione nel dire che il sovraccarico è un tipo di polimorfismo, che ho cercato di giustificare nella mia domanda e risposta che in realtà si concentra sul sovraccarico è il polimorfismo o meno. Ho cercato di giustificare la risposta di Gabeg digitale presente in questa discussione. Fare riferimento a Elaborazione: il sovraccarico del metodo è un legame statico / tempo di compilazione ma non polimorfismo. È corretto correlare il legame statico con il polimorfismo?
PraveenKumar Lalasangi,

Risposte:


894

Il modo più chiaro per esprimere il polimorfismo è tramite una classe base (o interfaccia) astratta

public abstract class Human{
   ...
   public abstract void goPee();
}

Questa classe è astratta perché il goPee()metodo non è definibile per gli umani. È definibile solo per le sottoclassi maschio e femmina. Inoltre, Human è un concetto astratto: non è possibile creare un essere umano che non sia né maschio né femmina. Deve essere l'uno o l'altro.

Quindi ritardiamo l'implementazione usando la classe astratta.

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

e

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

Ora possiamo dire a un'intera stanza piena di Umani di fare pipì.

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

L'esecuzione di questo produrrebbe:

Stand Up
Sit Down
...

37
@yuudachi. Ho trovato questo esempio durante l'insegnamento di una lezione. La classe canonica "Conto bancario" non esprimeva realmente l '"astrattezza" della classe base. L'altro esempio canonico (Animal, make noise) era troppo astratto per essere compreso. Stavo cercando una singola base con sottoclassi troppo evidenti. In realtà, goPee () è stato l'unico esempio che mi è venuto in mente che non era sessista o stereotipato. (anche se in classe, ho stampato "in fondo al corridoio a sinistra" invece di alzarmi o sedermi.)
Chris Cudmore,

100
Questo esempio evidenzia anche la difficoltà di utilizzare un sistema gerarchico per descrivere i sistemi biologici. Alcuni umani, come i giovanissimi, fanno pipì in quasi tutte le posizioni - e ai bambini non è facile dire a goPee (). Alcuni umani sono intersessuali, dove le etichette biologiche di "maschio" o "femmina" diventano piuttosto mal definite; i significati sociali sono ancora più complessi. Come esempio di insegnamento, mostra come le ipotesi di modellistica possano avere risultati negativi, come l'implicazione che qualcuno (ad esempio, uno studente di programmazione OO) che è incontinente o intersessuale non è in realtà umano.
Andrew Dalke,

7
Mi viene in mente almeno una manciata di umani che smentirebbero la tua tesi "non puoi creare un essere umano che non è né maschio né femmina", anche se sarebbe ancora vero per il tuo codice ... cattiva astrazione suppongo di dire ? ;)
Frank W. Zammetti,

2
Penso che sia importante sottolineare che è solo il polimorfismo perché quale versione di goPee () chiamare può essere determinata solo in fase di esecuzione. Mentre questo esempio lo implica, è bello sottolineare perché esattamente questo è il polimorfismo. Inoltre, non richiede lezioni di pari livello. Può anche essere una relazione genitore-figlio. O anche classi completamente non correlate che per coincidenza hanno la stessa funzione. Un esempio di ciò può essere la funzione .toString (). Che può essere chiamato in modo casuale su qualsiasi oggetto, ma il compilatore non può mai sapere esattamente quale tipo di oggetto.
Tor Valamo,

20
@AndrewDalke, +1 per le note sulla complessità biologica. Inoltre, goPeenon accetta un campo gravitazionale come input. Questa dipendenza dallo stato globale rende CatheterizedIntersexAstronautdifficile il test unitario e mostra che la sottoclasse potrebbe non essere sempre il metodo migliore per la composizione dei tratti.
Mike Samuel,

99

Il polimorfismo è la capacità di un'istanza di classe di comportarsi come se fosse un'istanza di un'altra classe nel suo albero ereditario, molto spesso una delle sue classi antenate. Ad esempio, in Java tutte le classi ereditano da Object. Pertanto, è possibile creare una variabile di tipo Object e assegnargli un'istanza di qualsiasi classe.

Una sostituzioneè un tipo di funzione che si verifica in una classe che eredita da un'altra classe. Una funzione di sostituzione "sostituisce" una funzione ereditata dalla classe base, ma lo fa in modo tale da essere chiamata anche quando un'istanza della sua classe finge di essere di tipo diverso attraverso il polimorfismo. Facendo riferimento all'esempio precedente, è possibile definire la propria classe e sovrascrivere la funzione toString (). Poiché questa funzione è ereditata da Object, sarà comunque disponibile se si copia un'istanza di questa classe in una variabile di tipo Object. Normalmente, se chiami toString () sulla tua classe mentre sta fingendo di essere un oggetto, la versione di toString che verrà effettivamente attivata è quella definita sull'oggetto stesso. Tuttavia, poiché la funzione è una sostituzione, la definizione di toString () della tua classe viene utilizzata anche quando l'istanza della classe "

Il sovraccarico è l'azione di definire più metodi con lo stesso nome, ma con parametri diversi. Non è correlato né al superamento né al polimorfismo.


8
Questo è vecchio ma il polimorfismo non implica che l'altra classe debba essere nella struttura ereditaria. Lo fa in Java se si considera che le interfacce fanno parte della struttura ereditaria, ma non in Go, dove le interfacce sono implementate implicitamente.
JN

5
In realtà, non hai bisogno di lezioni per il polimorfismo.
StCredZero,

3
Sono un novizio e mi correggo se sbaglio, ma non direi che il sovraccarico non è correlato al polimorfismo. Almeno in Java, il polimorfismo si verifica quando l'implementazione viene scelta in base al tipo di chiamante e il sovraccarico è quando l'implementazione viene scelta in base al tipo di parametri, non è vero? Vedere la somiglianza tra i due mi aiuta a capirlo.
csjacobs24,

9
Non corretto. Ad hoc polymorphismè quello che hai descritto nella sezione Sovraccarico ed è un caso di polimorfismo.
Jossie Calderon,

1
"Non è correlato né al superamento né al polimorfismo". Questa affermazione è sbagliata.
Shailesh Pratapwar,

45

Polimorfismo significa più di una forma, lo stesso oggetto esegue diverse operazioni in base al requisito.

Il polimorfismo può essere ottenuto usando due modi, quelli sono

  1. Sostituzione del metodo
  2. Metodo sovraccarico

Il sovraccarico del metodo significa scrivere due o più metodi nella stessa classe usando lo stesso nome di metodo, ma i parametri di passaggio sono diversi.

La sostituzione del metodo significa che usiamo i nomi dei metodi nelle diverse classi, ciò significa che il metodo della classe genitore viene utilizzato nella classe figlio.

In Java per ottenere il polimorfismo una variabile di riferimento della superclasse può contenere l'oggetto della sottoclasse.

Per ottenere il polimorfismo ogni sviluppatore deve usare gli stessi nomi di metodo nel progetto.


4
+1 per una bella risposta. La risposta accettata spiega solo un tipo di polimorfismo. Questa risposta è completa
apadana,

1
il polimorfismo è un paradigma (OOP), ma l'override e il sovraccarico sono strutture linguistiche.
曾 其 威

Il polimorfismo può anche essere ottenuto per tipo generico.
Minh Nghĩa,

43

Ecco un esempio di polimorfismo in pseudo-C # / Java:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

La funzione Main non conosce il tipo di animale e dipende dal comportamento di una particolare implementazione del metodo MakeNoise ().

Modifica: sembra che Brian mi abbia battuto sul pugno. Divertente abbiamo usato lo stesso esempio. Ma il codice sopra dovrebbe aiutare a chiarire i concetti.


È un esempio di polimorfismo di runtime. Il polimorfismo del tempo di compilazione è anche possibile attraverso il sovraccarico del metodo e tipi generici.
Pete Kirkham,

Forma -> Parallelogramma -> Rettangolo -> Quadrato
mpen

@ yankee2905 in questo caso, penso che potresti usare le interfacce, dal momento che una classe potrebbe implementare più interfacce.
Sam003,

1
@Zhisheng O aggiungendo un metodo di pipì nella classe genitore astratta? Vorrei utilizzare l'interfaccia per implementare qualcos'altro.
Joey Rohan,

42

Sia l'override che il sovraccarico sono usati per ottenere il polimorfismo.

È possibile disporre di un metodo in una classe che viene sovrascritto in una o più sottoclassi. Il metodo esegue operazioni diverse a seconda della classe utilizzata per creare un'istanza di un oggetto.

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

Potresti anche avere un metodo che è sovraccarico di due o più serie di argomenti. Il metodo fa cose diverse in base al tipo (i) di argomento (i) passato (i).

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

Suppongo che sia stato annullato perché storicamente il sovraccarico del metodo non è considerato parte del polimorfismo nel paradigma orientato agli oggetti. Il sovraccarico del metodo e il polimorfismo sono due caratteristiche ortogonali e indipendenti di un linguaggio di programmazione.
Sergio Acosta,

7
Come ho affermato nella mia risposta qui, non sono d'accordo: le due caratteristiche non sono ortogonali, ma sono strettamente correlate. Polimorfismo! = Eredità. Hai il mio voto positivo.
Peter Meyer,

2
In altre parole, digita polimorfismo vs. polimorfismo ad hoc. Sto valutando questa risposta, anche se non completa come dovrebbe, perché afferma correttamente che sia il sovraccarico che l'override sono correlati al polimorfismo. Dire che il polimorfismo nei linguaggi OOP può essere raggiunto solo tramite l'eredità di classe è semplicemente sbagliato: dovremmo ricordare che ci sono alcuni altri linguaggi OOP oltre a Java e C ++, dove si possono usare concetti come dispacciamento multiplo, polimorfismo ad hoc, polimorfismo parametrico e così via .
rsenna,

2
@rsenna Questo potrebbe essere incompleto ma risponde alla domanda molto meglio degli altri IMHO. Inoltre, molto bello che tu abbia menzionato il polimorfismo ad hoc e parametrico.
Valentin Radu,

15

Hai ragione che il sovraccarico non è la risposta.

Nessuno dei due ha la precedenza. La sostituzione è il mezzo con cui si ottiene il polimorfismo. Il polimorfismo è la capacità di un oggetto di variare il comportamento in base al suo tipo. Ciò è meglio dimostrato quando il chiamante di un oggetto che presenta polimorfismo non è a conoscenza del tipo specifico di oggetto.


3
Non dovrebbe essere il comportamento dell'oggetto a cambiare, ma la sua implementazione. Stesso comportamento, diversa implementazione, questo è polimorfismo.
QBziZ,

@QBziZ È necessario definire il comportamento , in particolare l'aggettivo stesso . Se il comportamento è lo stesso, perché la loro implementazione dovrebbe essere diversa? Non è che qualcuno non sia soddisfatto di una certa implementazione, quindi ne richiede una diversa.
Sнаđошƒаӽ,

11

In particolare, dire sovraccarico o scavalcamento non dà il quadro completo. Il polimorfismo è semplicemente la capacità di un oggetto di specializzare il suo comportamento in base al suo tipo.

Non sarei d'accordo con alcune delle risposte qui in quanto il sovraccarico è una forma di polimorfismo (polimorfismo parametrico) nel caso in cui un metodo con lo stesso nome possa comportarsi in modo diverso dando diversi tipi di parametri. Un buon esempio è il sovraccarico dell'operatore. Puoi definire "+" per accettare diversi tipi di parametri - diciamo stringhe o int - e in base a questi tipi, "+" si comporterà diversamente.

Il polimorfismo include anche metodi di ereditarietà e di prevalenza, sebbene possano essere astratti o virtuali nel tipo di base. In termini di polimorfismo basato sull'ereditarietà, Java supporta solo l'ereditarietà di una sola classe limitandone il comportamento polimorfico a quello di una singola catena di tipi di base. Java supporta l'implementazione di più interfacce che è ancora un'altra forma di comportamento polimorfico.


Hai ragione in termini di cosa significano le parole coinvolte in generale, ma in un contesto di programmazione, quando le persone dicono "polimorfismo" significano sempre "polimorfismo basato sull'eredità". Punto interessante, ma penso che descrivere il polimorfismo in questo modo confonderà le persone.
The Digital Gabeg,

Potrebbe essere più semplice spiegare il polimorfismo solo in termini di ereditarietà, ma il modo in cui questa particolare domanda è stata posta penso che sia prudente descrivere anche il polimorfismo parametrico.
Patrick McElhaney,

4
Per essere chiari, penso che debbano essere dichiarate le diverse forme - cosa che non ho nemmeno fatto adeguatamente - perché qui ci sono alcune risposte che sono presentate come assolute. Non sono d'accordo sul fatto che nel "contesto del programmatore ..." polimorfismo "significa sempre" polimorfismo basato sull'ereditarietà ""
Peter Meyer,

2
penso che il sovraccarico sia meglio classificato come Ad-hoc_polymorphism en.wikipedia.org/wiki/…
Manu

Tendo a concordare con "The Digital Gabeg" sul seguito. Se stai discutendo di OOP, il polimorfismo di solito significa polimorfismo di sottotipo, e se stai discutendo di teoria dei tipi significa qualsiasi tipo di polimorfismo.
Manu,

7

Il polimorfismo significa semplicemente "molte forme".

Non RICHIEDE l'ereditarietà per raggiungere ... poiché l'implementazione dell'interfaccia, che non è affatto eredità, soddisfa i bisogni polimorfici. Probabilmente, l'implementazione dell'interfaccia soddisfa le esigenze polimorfiche "Meglio" dell'ereditarietà.

Ad esempio, creeresti una superclasse per descrivere tutte le cose che possono volare? Non dovrei pensare di no. Saresti meglio servito per creare un'interfaccia che descriva il volo e lasciarlo a quello.

Pertanto, poiché le interfacce descrivono il comportamento e i nomi dei metodi descrivono il comportamento (per il programmatore), non è troppo lontano considerare il sovraccarico del metodo come una forma minore di polimorfismo.


2
Sicuramente la migliore risposta ancora. Il polimorfismo può essere applicato a tutti i costrutti del linguaggio, siano essi nomi (classi) o verbi (metodi).
Radu Gasler,

6

L'esempio classico, Cani e gatti sono animali, gli animali hanno il metodo makeNoise. Posso iterare attraverso una serie di animali che chiamano makeNoise su di loro e mi aspetto che possano fare lì le rispettive implementazioni.

Il codice chiamante non deve sapere che animale specifico sono.

Questo è quello che penso come polimorfismo.


4

Il polimorfismo è la capacità di un oggetto di apparire in più forme. Ciò implica l'utilizzo dell'ereditarietà e delle funzioni virtuali per costruire una famiglia di oggetti che possono essere scambiati. La classe base contiene i prototipi delle funzioni virtuali, possibilmente non implementate o con implementazioni predefinite come impone l'applicazione, e le varie classi derivate le implementano in modo diverso per influenzare comportamenti diversi.


4

Nessuno dei due:

Il sovraccarico è quando si ha lo stesso nome di funzione che accetta parametri diversi.

La sostituzione è quando una classe figlio sostituisce il metodo di un genitore con uno proprio (questo in sé non costituisce polimorfismo).

Il polimorfismo è in ritardo vincolante, ad esempio i metodi della classe base (padre) vengono chiamati ma non fino a quando il runtime non conosce quale sia l'oggetto reale - potrebbe essere una classe figlio i cui metodi sono diversi. Questo perché è possibile utilizzare qualsiasi classe figlio in cui è definita una classe base.

In Java vedi molto il polimorfismo con la libreria delle collezioni:

int countStuff(List stuff) {
  return stuff.size();
}

Elenco è la classe di base, il compilatore non ha idea se stai contando un elenco collegato, un vettore, un array o un'implementazione di un elenco personalizzato, purché si comporti come un Elenco:

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

Se sovraccaricassi avresti:

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

e la versione corretta di countStuff () verrebbe scelta dal compilatore per corrispondere ai parametri.


4

Anche se, il polimorfismo è già spiegato in dettaglio in questo post, ma vorrei porre maggiormente l'accento sul perché parte di esso.

Perché il polimorfismo è così importante in qualsiasi linguaggio OOP.

Proviamo a creare una semplice applicazione per una TV con e senza ereditarietà / polimorfismo. Pubblica ogni versione dell'applicazione, facciamo una piccola retrospettiva.

Supponiamo che tu sia un ingegnere del software in una società televisiva e ti viene chiesto di scrivere software per i controller di volume, luminosità e colore per aumentare e diminuire i loro valori su comando dell'utente.

Si inizia con la scrittura di classi per ciascuna di queste funzionalità aggiungendo

  1. set: - Per impostare un valore di un controller (supponendo che questo abbia un codice specifico del controller)
  2. get: - Per ottenere il valore di un controller (supponendo che questo abbia un codice specifico del controller)
  3. regolare: - Per convalidare l'ingresso e impostare un controller (convalide generiche .. indipendentemente dai controller)
  4. mappatura dell'input dell'utente con i controller: - Per ottenere l'input dell'utente e richiamare i controller di conseguenza.

Versione applicazione 1

import java.util.Scanner;    
class VolumeControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV1    {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

/*
 *       There can be n number of controllers
 * */
public class TvApplicationV1 {
    public static void main(String[] args)  {
        VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
        BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
        ColourControllerV1 colourControllerV1 = new ColourControllerV1();


        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println("Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV1.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV1.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV1.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV1.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV1.adjust(5);
                    break;
                }
                case 6: {
                colourControllerV1.adjust(-5);
                break;
            }
            default:
                System.out.println("Shutting down...........");
                break OUTER;
        }

    }
    }
}

Ora hai la nostra prima versione dell'applicazione funzionante pronta per essere distribuita. È tempo di analizzare il lavoro svolto finora.

Problemi nell'applicazione TV versione 1

  1. Il codice di regolazione (valore int) è duplicato in tutte e tre le classi. Si desidera ridurre al minimo la duplicità del codice. (Ma non hai pensato al codice comune e spostandolo in qualche super classe per evitare il codice duplicato)

Decidi di convivere finché l'applicazione funzionerà come previsto.

Dopo qualche volta, il tuo capo torna da te e ti chiede di aggiungere la funzionalità di ripristino all'applicazione esistente. Il reset imposterà tutti e 3 i tre controller sui rispettivi valori predefiniti.

Si inizia a scrivere una nuova classe (ResetFunctionV2) per la nuova funzionalità e si mappa il codice di mappatura dell'input dell'utente per questa nuova funzionalità.

Versione dell'applicazione 2

import java.util.Scanner;
class VolumeControllerV2    {

    private int defaultValue = 25;
    private int value;

    int getDefaultValue() {
        return defaultValue;
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV2   {

    private int defaultValue = 50;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV2    {

    private int defaultValue = 40;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class ResetFunctionV2 {

    private VolumeControllerV2 volumeControllerV2 ;
    private BrightnessControllerV2 brightnessControllerV2;
    private ColourControllerV2 colourControllerV2;

    ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2)  {
        this.volumeControllerV2 = volumeControllerV2;
        this.brightnessControllerV2 = brightnessControllerV2;
        this.colourControllerV2 = colourControllerV2;
    }
    void onReset()    {
        volumeControllerV2.set(volumeControllerV2.getDefaultValue());
        brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
        colourControllerV2.set(colourControllerV2.getDefaultValue());
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV2 {
    public static void main(String[] args)  {
        VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
        BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
        ColourControllerV2 colourControllerV2 = new ColourControllerV2();

        ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV2.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV2.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV2.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV2.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV2.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV2.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV2.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Quindi l'applicazione è pronta con la funzione Reimposta. Ma ora inizi a rendertene conto

Problemi nell'applicazione TV versione 2

  1. Se al prodotto viene introdotto un nuovo controller, è necessario modificare il codice di reimpostazione.
  2. Se il conteggio del controller aumenta molto, avresti problemi a conservare i riferimenti dei controller.
  3. Il codice funzione di ripristino è strettamente associato a tutto il codice della classe dei controller (per ottenere e impostare i valori predefiniti).
  4. La classe di funzionalità di ripristino (ResetFunctionV2) può accedere ad altri metodi della classe Controller (regolazione) che non sono desiderabili.

Allo stesso tempo, si sente dal capo che potrebbe essere necessario aggiungere una funzionalità in cui ciascuno dei controller, all'avvio, deve verificare la versione più recente del driver dal repository di driver ospitato dell'azienda tramite Internet.

Ora inizi a pensare che questa nuova funzionalità da aggiungere assomigli alla funzione di ripristino e ai problemi dell'applicazione (V2) verrà moltiplicata se non ricodificherai la tua applicazione.

Inizi a pensare di utilizzare l'ereditarietà in modo da poter trarre vantaggio dall'abilità polimorfica di JAVA e aggiungere una nuova classe astratta (ControllerV3) a

  1. Dichiarare la firma del metodo get e set.
  2. Contiene l'implementazione del metodo di regolazione precedentemente replicata tra tutti i controller.
  3. Dichiarare il metodo setDefault in modo che la funzione di ripristino possa essere facilmente implementata sfruttando il polimorfismo.

Con questi miglioramenti, hai la versione 3 dell'applicazione TV pronta con te.

Versione dell'applicazione 3

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

abstract class ControllerV3 {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
    abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3   {

    private int defaultValue = 25;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
}
class  BrightnessControllerV3  extends ControllerV3   {

    private int defaultValue = 50;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
}
class ColourControllerV3 extends ControllerV3   {

    private int defaultValue = 40;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
}

class ResetFunctionV3 {

    private List<ControllerV3> controllers = null;

    ResetFunctionV3(List<ControllerV3> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (ControllerV3 controllerV3 :this.controllers)  {
            controllerV3.setDefault();
        }
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV3 {
    public static void main(String[] args)  {
        VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
        BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
        ColourControllerV3 colourControllerV3 = new ColourControllerV3();

        List<ControllerV3> controllerV3s = new ArrayList<>();
        controllerV3s.add(volumeControllerV3);
        controllerV3s.add(brightnessControllerV3);
        controllerV3s.add(colourControllerV3);

        ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV3.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV3.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV3.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV3.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV3.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV3.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV3.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Sebbene la maggior parte del problema elencato nell'elenco dei numeri di V2 sia stato risolto tranne

Problemi nell'applicazione TV versione 3

  1. La classe di funzionalità di ripristino (ResetFunctionV3) può accedere ad altri metodi della classe Controller (regolazione) che non sono desiderabili.

Ancora una volta, pensi di risolvere questo problema, poiché ora hai anche un'altra funzione (aggiornamento del driver all'avvio) da implementare. Se non lo risolvi, verrà replicato anche in nuove funzionalità.

Quindi dividi il contratto definito in classe astratta e scrivi 2 interfacce per

  1. Funzione di ripristino
  2. Aggiornamento driver.

E fai implementare la tua prima classe concreta come di seguito

Versione dell'applicazione 4

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

interface OnReset {
    void setDefault();
}
interface OnStart {
    void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class VolumeControllerV4 extends ControllerV4 {

    private int defaultValue = 25;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for VolumeController .... Done");
    }
}
class  BrightnessControllerV4 extends ControllerV4 {

    private int defaultValue = 50;
    private int value;
    @Override
    int get()    {
        return value;
    }
    @Override
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }

    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for BrightnessController .... Done");
    }
}
class ColourControllerV4 extends ControllerV4 {

    private int defaultValue = 40;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for ColourController .... Done");
    }
}
class ResetFunctionV4 {

    private List<OnReset> controllers = null;

    ResetFunctionV4(List<OnReset> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (OnReset onreset :this.controllers)  {
            onreset.setDefault();
        }
    }
}
class InitializeDeviceV4 {

    private List<OnStart> controllers = null;

    InitializeDeviceV4(List<OnStart> controllers)  {
        this.controllers = controllers;
    }
    void initialize()    {
        for (OnStart onStart :this.controllers)  {
            onStart.checkForDriverUpdate();
        }
    }
}
/*
*       so on
*       There can be n number of controllers
*
* */
public class TvApplicationV4 {
    public static void main(String[] args)  {
        VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
        BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
        ColourControllerV4 colourControllerV4 = new ColourControllerV4();
        List<ControllerV4> controllerV4s = new ArrayList<>();
        controllerV4s.add(brightnessControllerV4);
        controllerV4s.add(volumeControllerV4);
        controllerV4s.add(colourControllerV4);

        List<OnStart> controllersToInitialize = new ArrayList<>();
        controllersToInitialize.addAll(controllerV4s);
        InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
        initializeDeviceV4.initialize();

        List<OnReset> controllersToReset = new ArrayList<>();
        controllersToReset.addAll(controllerV4s);
        ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV4.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV4.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV4.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV4.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV4.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV4.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV4.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Ora tutto il problema affrontato è stato risolto e ti sei reso conto che con l'uso dell'ereditarietà e del polimorfismo potresti

  1. Mantieni le varie parti dell'applicazione accoppiate liberamente (i componenti della funzione di ripristino o di aggiornamento del driver non devono essere resi consapevoli delle classi effettive del controller (volume, luminosità e colore), qualsiasi classe che implementa OnReset o OnStart sarà accettabile per la funzione di ripristino o di aggiornamento del driver componenti rispettivamente).
  2. Il miglioramento dell'applicazione diventa più semplice (la nuova aggiunta del controller non influirà sul componente di reimpostazione o aggiornamento del driver e ora è davvero facile aggiungerne di nuovi)
  3. Mantieni il livello di astrazione (ora la funzione di ripristino può vedere solo il metodo setDefault dei controller e la funzione di ripristino può vedere solo il metodo checkForDriverUpdate dei controller)

Spero che sia di aiuto :-)


3

Il termine sovraccarico si riferisce ad avere più versioni di qualcosa con lo stesso nome, in genere metodi con elenchi di parametri diversi

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

Quindi queste funzioni potrebbero fare la stessa cosa ma hai la possibilità di chiamarlo con un ID o un nome. Non ha nulla a che fare con l'eredità, le classi astratte, ecc.

La sostituzione di solito si riferisce al polimorfismo, come hai descritto nella tua domanda


2

il sovraccarico è quando si definiscono 2 metodi con lo stesso nome ma parametri diversi

l'override è il punto in cui si modifica il comportamento della classe base tramite una funzione con lo stesso nome in una sottoclasse.

Quindi il polimorfismo è correlato all'override ma non al sovraccarico.

Tuttavia, se qualcuno mi ha dato una semplice risposta di "scavalcamento" per la domanda "Che cos'è il polimorfismo?" Vorrei chiedere ulteriori spiegazioni.


2

l'override è più come nascondere un metodo ereditato dichiarando un metodo con lo stesso nome e la stessa firma del metodo di livello superiore (metodo super), questo aggiunge un comportamento polimorfico alla classe. in altre parole, la decisione di scegliere quale metodo di livello da chiamare verrà presa in fase di esecuzione e non in fase di compilazione. questo porta al concetto di interfaccia e implementazione.


2

che cos'è il polimorfismo?

Dal tutorial di Java

La definizione del dizionario del polimorfismo si riferisce a un principio in biologia in cui un organismo o una specie può avere molte forme o fasi diverse. Questo principio può essere applicato anche alla programmazione orientata agli oggetti e ai linguaggi come il linguaggio Java. Le sottoclassi di una classe possono definire i propri comportamenti unici e tuttavia condividere alcune delle stesse funzionalità della classe genitore.

Considerando gli esempi e la definizione, l' override dovrebbe essere una risposta accettata.

Per quanto riguarda la tua seconda query:

SE tu avessi una classe base astratta che ha definito un metodo senza implementazione e hai definito quel metodo nella sottoclasse, è ancora prioritario?

Dovrebbe essere chiamato override.

Dai un'occhiata a questo esempio per comprendere i diversi tipi di sostituzione.

  1. La classe base non prevede alcuna implementazione e la sottoclasse deve sovrascrivere il metodo completo - (astratto)
  2. La classe base fornisce un'implementazione predefinita e la sottoclasse può modificare il comportamento
  3. La sottoclasse aggiunge l'estensione all'implementazione della classe base chiamando super.methodName() come prima istruzione
  4. La classe base definisce la struttura dell'algoritmo (metodo Template) e la sottoclasse avrà la precedenza su una parte dell'algoritmo

snippet di codice:

import java.util.HashMap;

abstract class Game implements Runnable{

    protected boolean runGame = true;
    protected Player player1 = null;
    protected Player player2 = null;
    protected Player currentPlayer = null;

    public Game(){
        player1 = new Player("Player 1");
        player2 = new Player("Player 2");
        currentPlayer = player1;
        initializeGame();
    }

    /* Type 1: Let subclass define own implementation. Base class defines abstract method to force
        sub-classes to define implementation    
    */

    protected abstract void initializeGame();

    /* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
    protected void logTimeBetweenMoves(Player player){
        System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
    }

    /* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
        super.methodName() in first line of the child class method and specific implementation later */
    protected void logGameStatistics(){
        System.out.println("Base class: logGameStatistics:");
    }
    /* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
    protected void runGame() throws Exception{
        System.out.println("Base class: Defining the flow for Game:");  
        while ( runGame) {
            /*
            1. Set current player
            2. Get Player Move
            */
            validatePlayerMove(currentPlayer);  
            logTimeBetweenMoves(currentPlayer);
            Thread.sleep(500);
            setNextPlayer();
        }
        logGameStatistics();
    }
    /* sub-part of the template method, which define child class behaviour */
    protected abstract void validatePlayerMove(Player p);

    protected void setRunGame(boolean status){
        this.runGame = status;
    }
    public void setCurrentPlayer(Player p){
        this.currentPlayer = p;
    }
    public void setNextPlayer(){
        if ( currentPlayer == player1) {
            currentPlayer = player2;
        }else{
            currentPlayer = player1;
        }
    }
    public void run(){
        try{
            runGame();
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class Player{
    String name;
    Player(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

/* Concrete Game implementation  */
class Chess extends Game{
    public Chess(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized Chess game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate Chess move:"+p.getName());
    }
    protected void logGameStatistics(){
        super.logGameStatistics();
        System.out.println("Child class: Add Chess specific logGameStatistics:");
    }
}
class TicTacToe extends Game{
    public TicTacToe(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized TicTacToe game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate TicTacToe move:"+p.getName());
    }
}

public class Polymorphism{
    public static void main(String args[]){
        try{

            Game game = new Chess();
            Thread t1 = new Thread(game);
            t1.start();
            Thread.sleep(1000);
            game.setRunGame(false);
            Thread.sleep(1000);

            game = new TicTacToe();
            Thread t2 = new Thread(game);
            t2.start();
            Thread.sleep(1000);
            game.setRunGame(false);

        }catch(Exception err){
            err.printStackTrace();
        }       
    }
}

produzione:

Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:

2

Penso che ragazzi state mescolando concetti. Il polimorfismo è la capacità di un oggetto di comportarsi diversamente in fase di esecuzione. Per raggiungere questo obiettivo, sono necessari due requisiti:

  1. Rilegatura tardiva
  2. Eredità.

Detto questo, sovraccarico significa qualcosa di diverso dall'override a seconda della lingua che stai utilizzando. Ad esempio in Java non esiste l' override ma il sovraccarico . I metodi sovraccarichi con firma diversa dalla sua classe base sono disponibili nella sottoclasse. Altrimenti verrebbero ignorati (per favore, vedi che intendo ora il fatto che non c'è modo di chiamare il tuo metodo di classe base dall'esterno dell'oggetto).

Tuttavia in C ++ non è così. Qualsiasi metodo sovraccarico , indipendentemente dal fatto che la firma sia uguale o meno (quantità diversa, tipo diverso) viene anch'esso ignorato . Cioè, il metodo della classe base non è più disponibile nella sottoclasse quando viene chiamato dall'esterno dell'oggetto sottoclasse, ovviamente.

Quindi la risposta è quando si parla di sovraccarico di Java . In qualsiasi altra lingua può essere diverso come accade in c ++


1

Il polimorfismo è più probabile per quanto riguarda il suo significato ... a OVERRIDING in java

Si tratta di comportamenti diversi dell'oggetto SAME in diverse situazioni (in termini di programmazione ... è possibile chiamare diversi ARGOMENTI)

Penso che l'esempio che segue ti aiuterà a capire ... Anche se non è un codice Java PURO ...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

Ma se cambiamo l'ARGOMENTO ... il COMPORTAMENTO verrà cambiato ...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

La persona (qui "l'oggetto") è la stessa ...


1

Il polimorfismo è una multipla implementazione di un oggetto o potresti dire più forme di un oggetto. diciamo che hai classe Animalscome classe base astratta e ha un metodo chiamato movement()che definisce il modo in cui l'animale si muove. Ora in realtà abbiamo diversi tipi di animali e si muovono in modo diverso anche alcuni con 2 zampe, altri con 4 e alcuni senza zampe, ecc. Per definire diversi movement()di ogni animale sulla terra, dobbiamo applicare il polimorfismo. Tuttavia, è necessario definire più classi, ad esempio classe Dogs Cats Fishecc. Quindi è necessario estendere quelle classi dalla classe base Animalse sovrascriverne il metodo movement()con una nuova funzionalità di movimento basata su ogni animale che si possiede. Puoi anche usareInterfacesper riuscirci. La parola chiave qui è prioritaria, il sovraccarico è diverso e non è considerato polimorfismo. con il sovraccarico è possibile definire più metodi "con lo stesso nome" ma con parametri diversi sullo stesso oggetto o classe.


0

Il polimorfismo si riferisce alla capacità di un linguaggio di trattare in modo uniforme un oggetto diverso usando una singola interfaccia; come tale è correlato all'override, quindi l'interfaccia (o la classe base) è polimorfica, l'implementatore è l'oggetto che sostituisce (due facce della stessa medaglia)

comunque, la differenza tra i due termini è meglio spiegata usando altri linguaggi, come c ++: un oggetto polimorfico in c ++ si comporta come controparte java se la funzione di base è virtuale, ma se il metodo non è virtuale il salto di codice viene risolto staticamente , e il tipo vero non è verificato in fase di esecuzione, quindi il polimorfismo include la capacità di un oggetto di comportarsi diversamente a seconda dell'interfaccia utilizzata per accedervi; lasciami fare un esempio in pseudocodice:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(supponendo che makeRumor NON sia virtuale)

java non offre davvero questo livello di polimorfismo (chiamato anche affettamento degli oggetti).

animal a = new dog (); cane b = nuovo cane ();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

in entrambi i casi verrà stampato solo woff .. poiché aeb si riferisce al cane di classe



animal a = new dog (); a è stato costruito come un cane e stampa "woff". Se vuoi che sia stampato, devi eseguire l'upgrade. ((Animale) a) .makeRumor ()
Chris Cudmore,

È un riferimento all'upgrade, ma l'oggetto è ancora un cane. Se vuoi che sia un animale, devi esplicitamente potenziare l'oggetto.
Chris Cudmore,

Capito. La domanda è stata taggata Java. Hai risposto a C ++. Potresti essere corretto in C ++. Sono decisamente corretto in Java.
Chris Cudmore,

dovrebbe accadere ogni volta che un costruttore di copie è coinvolto qui è un riferimento fredosaurus.com/notes-cpp/oop-condestructors/… caso tre partite; ignora il nuovo operatore che è lì solo per chiarire la creazione.
Lorenzo Boccaccia,

0
import java.io.IOException;

class Super {

    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName() + " - I'm parent");
        return null;
    }

}

class SubOne extends Super {

    @Override
    protected Super getClassName(Super s)  {
        System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
        return null;
    }

}

class SubTwo extends Super {

    @Override
    protected Super getClassName(Super s) throws NullPointerException {
        System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
        return null;
    }

}

class SubThree extends Super {

    @Override
    protected SubThree getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
        return null;
    }

}

class SubFour extends Super {

    @Override
    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
        return null;
    }

}

class SubFive extends Super {

    @Override
    public Super getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
        return null;
    }

}

class SubSix extends Super {

    public Super getClassName(Super s, String ol) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
        return null;
    }

}

class SubSeven extends Super {

    public Super getClassName(SubSeven s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
        return null;
    }

}

public class Test{

    public static void main(String[] args) throws Exception {

        System.out.println("Overriding\n");

        Super s1 = new SubOne(); s1.getClassName(null);

        Super s2 = new SubTwo(); s2.getClassName(null);

        Super s3 = new SubThree(); s3.getClassName(null);

        Super s4 = new SubFour(); s4.getClassName(null);

        Super s5 = new SubFive(); s5.getClassName(null);

        System.out.println("Overloading\n");

        SubSix s6 = new SubSix(); s6.getClassName(null, null);

        s6 = new SubSix(); s6.getClassName(null);

        SubSeven s7 = new SubSeven(); s7.getClassName(s7);

        s7 = new SubSeven(); s7.getClassName(new Super());

    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.