2010-01-20 10 views

risposta

9

ci saranno momenti in cui si hanno alcune inizializzazioni comuni di variabili di istanza che tutte le classi ereditative devono impostare. Crea un'istanza di una classe astratta quando la estendi e quella classe concreta ha un costruttore che fornirà i parametri al costruttore della classe astratta.

+2

Un esempio è javax.swing.AbstractAction –

5

Possono ancora essere invocati da costruttori di classi che ereditano da quello, rendendo il refactoring del codice un buon uso per avere un costruttore nella classe astratta.

3

Se si dispone di campi finali non inizializzati in una classe astratta, è necessario inizializzarli in un costruttore.

E.g.

abstract class A { 
    final int x; 
} 

non compilerà senza un costruttore che assegna a x.

3

Se la tua classe non dichiara un costruttore, javac creerà per te un costruttore no-arg, do-nothing. Quindi, quando la sottoclasse viene inizializzata, chiamerà il costruttore no-op generato e la vita è buona.

Tuttavia, se la tua classe dichiara un costruttore, javac NON ne farà uno per te. In tal caso, il costruttore della sottoclasse deve chiamare esplicitamente il costruttore della classe genitore. Altrimenti, non riuscirai a inizializzare i membri della classe genitore, come menzionato nella risposta sopra.

2

I costruttori per le classi astratte sono utilizzati da sottoclassi (richiamati dai costruttori di sottoclassi che utilizzano super(params)).

Si dovrebbe rendere questi costruttori protected per rendere chiaro.

2

Non si istanziano classi astratte ma il costruttore viene richiamato quando viene creata un'istanza di una sottoclasse.

L'utilizzo potrebbe essere l'inizializzazione di attributi comuni, ad es.

import java.util.List; 
import java.util.ArrayList; 
abstract class BaseClass { 
    protected List list; // visible from subclasses 

    public BaseClass() { 
     System.out.println("to abstract..."); 
     // common initialization to all subclasses 
     list = new ArrayList(); 
     list.add("a"); 
     list.add("a"); 
     list.add("a"); 
    } 
} 

class ConcreteClass extends BaseClass { 
    public ConcreteClass(){ 
     // The list is initialized already 
     System.out.println("now it is concrete and the list is: = "+ this.list); 


    } 
} 

class TestAbstractClass { 
    public static void main(String [] args) { 
     BaseClass instance = new ConcreteClass(); 
    } 

} 

uscita

$ java TestAbstractClass 
to abstract... 
now it is concrete and the list is: = [a, a, a] 
1

De-duplicazione comune conoscenza/comportamento.

E.g. una macchina: tutte le vostre auto saranno costruite da un corpo e quattro ruote e un motore. Quindi fai questa parte della costruzione nel costruttore per la classe Car astratta chiamando funzioni come Body(), Wheel (int x), Engine(). Ogni particolare classe di auto avrà la propria implementazione di Body(), Wheel() e Engine() - ma tutti faranno gli stessi passi per costruire l'auto da loro, quindi non c'è bisogno di duplicare quei passaggi in ognuno di questi classi. In questo caso si implementa questo comportamento comune nell'antenato.

-1

Sono d'accordo, I costruttori sono creati assumendo che ci saranno istanze. Se hai un sacco di codice comune puoi pensare di creare un Costruttore ma è molto meglio metterlo in un metodo init().

+1

questo è un cattivo consiglio, quindi ogni classe inheirting deve ricordare di chiamare super.init() e diventa fastidioso, questo è un consiglio non standard e davvero pessimo. –

Problemi correlati