2010-01-20 5 views

Répondre

9

Il y aura des moments où vous aurez une initialisation commune des variables d'instance que toutes les classes héritantes doivent mettre en place. Vous instanciez une classe abstraite lorsque vous l'étendez et cette classe concrète a un constructeur qui fournira les paramètres au constructeur de la classe abstraite.

+2

Un exemple est javax.swing.AbstractAction –

5

Ils peuvent toujours être invoqués par les constructeurs de classes qui en héritent, ce qui fait du refactoring de code une bonne utilisation pour avoir un constructeur dans la classe abstraite.

3

Si vous avez des champs finaux non-initialisés dans une classe abstraite, vous devrez les initialiser dans un constructeur.

E.g.

abstract class A { 
    final int x; 
} 

ne compilera pas sans un constructeur qui attribue à x.

3

Si votre classe ne déclare pas de constructeur, javac créera pour vous un constructeur sans-arg, do-nothing. Ensuite, lorsque votre sous-classe est initialisée, elle appelle le constructeur non-op généré et la vie est bonne. Cependant, si votre classe déclare un constructeur, javac n'en fera PAS un pour vous. Dans ce cas, le constructeur de la sous-classe doit appeler explicitement le constructeur de la classe parente. Sinon, vous ne parvenez pas à initialiser les membres de la classe parente, comme le mentionne la réponse ci-dessus.

2

Les constructeurs de classes abstraites sont utilisés par les sous-classes (invoquées à partir des constructeurs de sous-classes en utilisant super(params)).

Vous devriez rendre ces constructeurs protected pour que cela soit clair.

2

Vous n'instanciez pas les classes abstraites mais le constructeur est appelé lorsqu'une sous-classe est instanciée.

L'utilisation pourrait être d'initialiser des attributs communs ie.

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

} 

Sortie

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

De-duplication des connaissances communes/comportement.

E.g. une voiture: toutes vos voitures seront construites avec un corps et quatre roues et un moteur. Donc vous faites cette partie de la construction dans le constructeur de la classe Car abstraite en appelant des fonctions comme Body(), Wheel (int x), Engine(). Chaque classe de voiture particulière aura sa propre implémentation de Body(), Wheel() et Engine() - mais tous feront les mêmes étapes pour construire la voiture à partir d'eux, il n'y a donc pas besoin de dupliquer ces étapes dans chacun de ces Des classes. Dans ce cas, vous implémentez ce comportement commun dans l'ancêtre.

-1

Je suis d'accord, les constructeurs sont créés en supposant qu'il y aura des instances. Si vous avez beaucoup de code commun, vous pouvez penser à créer un constructeur, mais il est préférable de le mettre dans une méthode init().

+1

c'est un mauvais conseil, alors chaque classe inheirting doit se souvenir d'appeler super.init() et il devient vite en désordre, c'est un conseil non standard et vraiment mauvais. –

Questions connexes