2013-07-06 18 views
7

vi sono le seguenti classi:Java "astratto come" metodo con il corpo

public abstract class Super 
{ 
    public abstract void run(); 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     System.out.println("Method called"); 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     System.out.println("Method called"); 
     System.out.println("Sub2 called"); 
    } 
} 

come posso evitare che devo scrivere il "System.out.println (" metodo chiamato ");" due volte?

Grazie per le risposte

CalibeR.50

+1

Se ogni implementazione è la stessa, allora perché si astragga il metodo. – NINCOMPOOP

+0

Puoi mostrarci come viene chiamato il metodo 'run()'? –

+0

questo è solo un esempio, ci sarà più codice nei metodi di esecuzione in Sub1 e Sub2. –

risposta

12

Portare la funzionalità comune nella superclasse e definire un altro metodo astratto, per il quale le sottoclassi definiranno la propria implementazione.

public abstract class Super { 
    public void run() { 
     System.out.println("Method called"); 
     printMessage(); 
    } 
    abstract void printMessage(); 
} 

public class Sub1 extends Super { 
    @Override 
    void printMessage() { 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super { 
    @Override 
    void printMessage() { 
     System.out.println("Sub2 called"); 
    } 
} 

In questo modo è possibile evitare la duplicazione di chiamare il metodo comune della superclasse due volte.

+0

Ma non sono in grado di rendere privato il metodo "printMessage". È possibile rendere "eseguibile" solo richiamabile nel tuo esempio? –

+0

@ CalibeR.50 Se è privato, non sarà accessibile dalla superclasse. Tuttavia, puoi renderlo * pacchetto privato *, omettendo il modificatore del livello di accesso, e sarà visibile solo all'interno del pacchetto – user000001

+2

Oh, dimenticato di protetto. Proverò se funziona nel mio caso. Grazie –

1

Se si desidera che tutti sottoclassi ad avere un comportamento identico, quindi la tecnica corretta sarebbe quella di codificare il metodo solo nelle superclasse, permettendo alle sottoclassi di ereditare esso . Ma ciò eliminerebbe la necessità che la tua superclasse fosse astratta in questo caso, poiché implementerebbe il suo unico metodo.

+0

Vorrei modificare un esempio per chiarire cosa sto cercando di fare –

4

Si può mettere run() implementazione nella classe astratta:

// Super is still an abstract class 
public abstract class Super 
{ 
    // While method run is not an abstract method: 
    public void run() 
    { 
     System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    // There's no need of declaring run() here unless you want to change its behaviour 
} 

public class Sub2 extends Super 
{ 
} 

Nella versione modificata della tua domanda, si può semplicemente utilizzare una realizzazione corsa ereditato

// Super is still abstract 
public abstract class Super 
{ 
    // But method run is not abstract 
    public void run() 
    { 
     System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); // <- call Super.run() that prints "Method called" 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub2 called"); 
    } 
} 
+0

Ho modificato la mia domanda per chiarire che cosa sto cercando di fare esattamente –

+0

devi anche chiamare super.run() se decidi di sovrascriverlo metodo in Sub1 e Sub2 – veritas

+0

@ CalibeR.50 Ho modificato la mia risposta –

2

È possibile inserire il codice comune nel metodo super-classe e chiamarlo dai metodi della sub-classe.

public abstract class Super 
{ 
    public abstract void run(); 
    // code common to both the sub classes implemented 
    public void print() { 
    System.out.println("Method called"); 
    } 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
    print(); 
    System.out.println("Sub1 called"); 
    // sub class specific code here 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     print(); 
     System.out.println("Sub2 called"); 
     // sub class specific code here 
    } 
} 
+0

Sì, questo funzionerebbe. Ma non c'è la possibilità di forzare che il codice venga eseguito con "run"? –

2

utilizzare il "modello Template Method":

public class Super 
{ 
    public void template() { 
     System.out.println("Method called"); 
     run(); 
    } 

    public abstract void run(); 
} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() // out called before run 
    { 

    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() // out called before run 
    { 

    } 
} 

Aditionally è possibile effettuare run protetto.

3

Se parte dell'implementazione di run() è comune a Sub1 e Sub2, suggerisco di utilizzare semplicemente l'ereditarietà e l'esecuzione dell'override nelle sottoclassi. Ecco l'esempio di codice:

public abstract class Super 
{ 
    public void run() { 
     // Code shared by all subclasses 
     System.out.println("Method called"); 
    } 

} 

public class Sub1 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub1 called"); 
    } 
} 

public class Sub2 extends Super 
{ 
    @Override 
    public void run() 
    { 
     super.run(); 
     System.out.println("Sub2 called"); 
    } 
} 

Il trucco è che la classe Super può essere definita abstract, mentre l'attuazione metodi. Se si dispone di sottoclassi che non richiedono il codice condiviso, è possibile ignorare run() senza il codice super.run() e modificarlo.

Problemi correlati