Ragioni dietro il comportamento relativo al polimorfismo in java

5

Ho letto questo codice da qualche parte

class Foo {
    public int a;
    public Foo() {
        a = 3;
    }
    public void addFive() {
        a += 5;
    }
    public int getA() {
        System.out.println("we are here in base class!");
        return  a;
    }
}

public class Polymorphism extends Foo{
   public int a;
   public Poylmorphism() {
       a = 5;
   }
   public void addFive() {
       System.out.println("we are here !" + a);
       a += 5;
   }

   public int getA() {
        System.out.println("we are here in sub class!");
        return  a;
    }

    public static void main(String [] main) {
        Foo f = new Polymorphism();
        f.addFive();
        System.out.println(f.getA()); // SOP 1
        System.out.println(f.a);      // SOP 2
    }
}

Per SOP1 otteniamo risposta 10 e per SOP2 otteniamo risposta 3. La ragione per questo è che non è possibile sovrascrivere le variabili mentre è possibile farlo per i metodi. Ciò accade perché il tipo della variabile di riferimento viene controllato quando si accede a una variabile e il tipo dell'oggetto viene controllato quando si accede a un metodo. Ma mi chiedo, ma perché è così? Qualcuno può spiegarmi qual è la ragione di questo comportamento

    
posta Shades88 16.09.2012 - 14:16
fonte

2 risposte

4

Il tuo riferimento è di tipo Foo; non conosce il tipo di oggetto a cui si riferisce.

Anche con questo, l'ereditarietà rompe l'incapsulamento; permettendo anche ai campi di istanza di essere sovrascritti, l'incapsulamento si spezzerebbe ancora di più. Forse nella tua sottoclasse stai chiamando un metodo dalla superclasse che si riferisce allo stato del campo di istanza a. L'implementazione della superclasse è basata sul suo a (non può supporre che esista una superclasse e la sovrascriverà) e avrà un comportamento molto caotico se la cambi sovrascrivendola.

Inoltre, l'ereditarietà del campo dell'istanza non dovrebbe essere consentita poiché i campi dell'istanza dovrebbero essere resi privati.

    
risposta data 16.09.2012 - 14:43
fonte
1

This happens because type of the reference variable is checked when a variable is accessed and type of the object is checked when a method is accessed. But I am wondering, just why is it that way? Can anyone explain me what is the reason for this behaviour

Non è un problema di tipo, è un problema vincolante.

  • L'espressione f.a lega staticamente al campo in base al tipo dichiarato della variabile f perché i campi non possono essere sovrascritti. E il motivo per cui non possono essere sovrascritti è che potrebbe interrompere la sostituibilità (per i campi non privati) e interrompere i metodi dichiarati nel supertipo che usa il campo.

  • La chiamata f.getA() associa dinamicamente al metodo nell'oggetto reale per implementare il polimorfismo dinamico e per impedire ai chiamanti di rompere l'astrazione chiamando erroneamente un metodo che aveva stato sottoposto a override.

In breve, se il metodo di collegamento era diverso in entrambi i casi, il risultato netto sarebbe un linguaggio meno espressivo con problemi nel mantenimento dei limiti di astrazione.

La maggior parte, se non tutti, i linguaggi OO staticamente tipizzati funzionano in questo modo. (Se qualcuno conosce dei contro-esempi che sono anche tipizzati staticamente, si prega di commentare.)

    
risposta data 18.09.2012 - 03:47
fonte

Leggi altre domande sui tag