2015-02-19 12 views
7

Esempio:Java: la ricorsione nel main-class chiama sottoclasse metodo invece del proprio metodo

class MainClass { 
    public doIt() { 
     ... 
     else doIt(); 
    } 
} 

class SubClass extends MainClass { 
    @Override 
    public doIt() { 
     super.doIt(); 
     ... 
    } 
} 

Ora il problema è:

  • io chiamo SubClass.doIt()
  • MainClass .doIt() è chiamato
  • MainClass.doIt() effettua la ricorsione chiamando doIt()
    Ma: il SubClass.doIt() viene chiamato anziché MainClass.doIt()

Questo comportamento è molto strano e i problemi sono programmati! Ho provato a chiamare la ricorsione con this.doIt() ma questo non ha aiutato. Qualcuno ha un'idea?

Grazie mille per le risposte, questo problema è stato risolto.

+3

Questo è il polimorfismo per te. – GriffeyDog

+0

"* Questo è un comportamento molto strano *" non proprio, 'else doIt()' è uguale a 'else this.doIt()' ma 'this' si riferisce all'istanza corrente e grazie al codice di associazione dinamica (meccanismo di polimorfismo) dal metodo di classe più vicino al tipo corrente di 'this' è chiamato. Dal momento che la classe più vicina a 'Sottoclassella' che contiene' doIt' è 'Sottoclassella' stessa, questo codice viene invocato. – Pshemo

+0

Questo è il comportamento presunto. –

risposta

7

Questo è il comportamento presunto, non impostando un metodo final, ciò significa che può essere override n, quindi è necessario tenere sempre conto che qualcuno può farlo. Le chiamate a questo metodo non sono mai garantite per il metodo a quel livello.

È possibile però risolvere questo problema con eleganza, utilizzando un metodo (protected) final:

class MainClass { 

    protected final void innerDoIt() { //final: so no @Override 
     ... 
     else innerDoIt(); 
    } 

    public void doIt() { 
     innerDoIt(); 
    } 

} 

E poi:

class SubClass extends MainClass { 

    @Override 
    public doIt() { 
     super.doIt(); 
     ... 
    } 
} 

final assicura, il metodo non può essere sovrascritto. Quindi, in quel momento, hai un contratto (garanzia) che il metodo innerDoIt è effettivamente il metodo innerDoIt che pensi sia.

Quindi nel caso non si desidera che il chiamante venga sostituito da, semplicemente lo si tesse in un altro metodo final. Rendendolo da protected, questo metodo può anche essere chiamato dallo SubClass.

+0

ok non lo sapevo, un miracolo che tutte le mie cose finiscono ora: p - grazie mille – Sneedlewoods

1
public class Main { 

    public static void main(String[] args) { 
     B b = new B(); 
     b.doIt(); 
     System.out.println(); 
     A a = new B(); 
     a.doIt(); 
    } 


    public static class A{ 
     boolean check=false; 
     public void doIt(){ 
      System.out.println("A start"); 
      if(check){ 

      } 
      else{ 
       check = true; 
       doIt(); 
      } 
      System.out.println("A end"); 
     } 
    } 
    public static class B extends A{ 
     @Override 
     public void doIt() { 
      System.out.println("B start"); 
      super.doIt(); 
      System.out.println("B end"); 
     } 
    } 
} 

In questo esempio, sia b e a sono istanze della classe B, così come probabilmente aspetta, a.doIt() e b.doIt() sarà in uscita lo stesso risultato.

B start 
A start 
B start 
A start 
A end 
B end 
A end 
B end 

B start 
A start 
B start 
A start 
A end 
B end 
A end 
B end 

Quando si chiama doIt(), si sta implicitamente chiamando this.doIt(), e this è un'istanza della classe B. Non c'è sintassi per fare ciò che vuoi fare senza separare il contenuto di doIt() (vedi risposta di CommuSoft)

Problemi correlati