Domanda

In termini di Java, quando qualcuno chiede:

  

che cos'è il polimorfismo?

sovraccarico o scavalcamento 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 sovraccarico non sia la risposta giusta di sicuro.

È stato utile?

Soluzione

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 metodo goPee () non è definibile per gli umani. È definibile solo per le sottoclassi maschio e femmina. Inoltre, Human è un concetto astratto & # 8212; Non puoi creare un essere umano che non sia né maschio né femmina. Deve essere l'uno o l'altro.

Quindi rinviamo 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
...

Altri suggerimenti

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, puoi creare una variabile di tipo Object e assegnargli un'istanza di qualsiasi classe.

Un override è un tipo di funzione che si verifica in una classe che eredita da un'altra classe. Una funzione di override "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 il vero tipo dell'istanza della classe è nascosto dietro il polimorfismo.

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

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 a pugni. Divertente abbiamo usato lo stesso esempio. Ma il codice sopra dovrebbe aiutare a chiarire i concetti.

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

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.

Sostituzione del metodo significa che utilizziamo 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.

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

Potresti avere un metodo in una classe     che è sovrascritto in uno o     più sottoclassi. Il metodo fa     cose diverse a seconda di quale     La classe è stata 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 con due o più serie di argomenti. Il metodo fa     cose diverse basate sul     tipo (i) di argomento (i) superato (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);
        }
    }

Hai ragione sul fatto 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 di quale tipo specifico sia l'oggetto.

In particolare dicendo che il sovraccarico o l'override non fornisce 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 dare diversi tipi di parametri. Un buon esempio è il sovraccarico dell'operatore. Puoi definire " + " 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 sostituzione, 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.

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 "Migliore" dell'eredità.

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.

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

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 farebbero lì rispettive implementazioni.

Il codice chiamante non deve sapere quale specifico animale sia.

Questo è quello che penso come polimorfismo.

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 richiesto dall'applicazione, e le varie classi derivate le implementano in modo diverso per influenzare comportamenti diversi.

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 si lega in ritardo, ad es. i metodi della classe base (genitore) 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 stavi sovraccaricando 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.

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

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

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 è legato alla prevalenza ma non al sovraccarico reale.

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

sovrascrivere è 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.

  

che cos'è il polimorfismo?

Da java tutorial

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, overriding dovrebbe essere accettata la risposta.

Per quanto riguarda la tua seconda query:

  

SE hai avuto 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();
        }       
    }
}

uscita:

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:

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

  1. Late Binding
  2. Inheritance.

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

Comunque in C ++ non è così. Qualsiasi metodo sovraccarico , indipendentemente dal fatto che la firma sia uguale o meno (importo diverso, tipo diverso), è anche 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 Java usare sovraccarico . In qualsiasi altra lingua può essere diverso come accade in c ++

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 controller di volume, luminosità e colore per aumentare e diminuire i loro valori su comando dell'utente.

Inizi a scrivere classi per ognuna di queste funzioni 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. regola: - Per convalidare l'input e impostare un controller. (Convalide generiche .. indipendenti dai controller)
  4. mappatura dell'input dell'utente con i controller: - Per ottenere l'input dell'utente e invocare 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.

  

A volte, il tuo Boss torna da te e ti chiede di aggiungere la funzionalità di ripristino all'applicazione esistente. Il ripristino imposta tutti e 3 i controller sui rispettivi valori predefiniti.

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

  

Versione 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 viene introdotto un nuovo controller nel prodotto, è 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 di reimpostazione della funzione è strettamente associato a tutti i codici della classe controller (per ottenere e impostare i valori predefiniti).
  4. Il ripristino della classe di funzionalità (ResetFunctionV2) può accedere ad altri metodi della classe Controller (regolazione) che non sono desiderabili.
  

Allo stesso tempo, senti il ??tuo capo che potresti dover aggiungere una funzione in cui ciascuno dei controller, all'avvio, deve controllare l'ultima versione del driver dal repository di driver ospitato dalla società tramite Internet.

Ora inizi a pensare che questa nuova funzione da aggiungere assomigli alla funzione Ripristina e i problemi dell'applicazione (V2) verranno moltiplicati se non ricerti la tua applicazione.

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

  1. Dichiara la firma del metodo get e set.
  2. Contiene l'implementazione del metodo di regolazione precedentemente replicata tra tutti i controller.
  3. Dichiara 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. Ripristina la classe di funzionalità (ResetFunctionV3) può accedere ad altri metodi della classe Controller (regolare) 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. Ripristina funzionalità.
  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 che hai 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 aggiornamento 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 Componenti delle funzioni di ripristino o aggiornamento driver 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 per te 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 questo aiuti :-)

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

Si tratta di comportamenti diversi dell'oggetto SAME in diverse situazioni (in termini di programmazione ... puoi chiamare ARGUMENTI diversi)

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'ARGUMENTO ... il COMPORTAMENTO verrà cambiato ...

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

La persona (qui l'oggetto " Oggetto ") è lo stesso ...

Il polimorfismo è un'implementazione multipla di un oggetto o potresti dire più forme di un oggetto. supponiamo che tu abbia la classe Animali come la 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 movimento () di ogni animale sulla terra, dobbiamo applicare il polimorfismo. Tuttavia, è necessario definire più classi, ad esempio la classe Cani Gatti Pesci ecc. Quindi è necessario estendere tali classi dalla classe di base Animali e sovrascrive il suo metodo movement () con una nuova funzionalità di movimento basata su ogni animale che possiedi. Puoi anche usare Interfaces per raggiungere questo obiettivo. La parola chiave qui è prioritaria, il sovraccarico è diverso e non è considerato polimorfismo. con il sovraccarico puoi definire più metodi " con lo stesso nome " ma con parametri diversi sullo stesso oggetto o classe.

Il polimorfismo si riferisce alla capacità di una lingua di avere un oggetto diverso trattato in modo uniforme usando una singola interfaccia; in quanto tale è legato alla sostituzione, quindi l'interfaccia (o la classe base) è polimorfica, l'implementatore è l'oggetto che ha la precedenza (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 del codice è 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 veramente 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 stamperà solo woff .. poiché aeb si riferisce al cane di classe

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());

    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top