web-dev-qa-db-fra.com

Une classe abstraite peut-elle avoir un constructeur?

Une classe abstraite peut-elle avoir un constructeur?

Si oui, comment peut-il être utilisé et à quelles fins?

529
Szere Dyeri

Oui, une classe abstraite peut avoir un constructeur. Considère ceci:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

La super-classe Product est abstraite et possède un constructeur. La classe concrète TimesTwo a un constructeur qui code simplement la valeur 2. La classe concrète TimesWhat a un constructeur qui permet à l'appelant de spécifier la valeur.

Les constructeurs abstraits seront fréquemment utilisés pour appliquer des contraintes de classe ou des invariants tels que les champs minimum requis pour configurer la classe.

NOTE: Comme il n'y a pas de constructeur par défaut (ou no-arg) dans le parent classe abstraite, le constructeur utilisé dans la sous-classe doit explicitement appeler le constructeur parent.

573

Vous définiriez un constructeur dans une classe abstraite si vous êtes dans l'une des situations suivantes:

  • vous voulez effectuer une initialisation .__ (vers des champs de la classe abstract) avant l'instanciation d'une sous-classe réellement a lieu
  • vous avez défini des champs finaux dans la classe abstraite mais vous ne les avez pas initialisés dans la déclaration elle-même; dans ce cas, vous DEVEZ avoir un constructeur pour initialiser ces champs

Notez que:

  • vous pouvez définir plus d'un constructeur (avec différents arguments )
  • vous pouvez (devriez?) définir tous vos constructeurs protégés (les rendre public est inutile de toute façon)
  • vos constructeurs de sous-classes peuvent.__ appeler un constructeur de la classe abstraite .__; il peut même avoir à l'appeler (s'il n'y a pas de constructeur no-argin dans la classe abstraite)

Dans tous les cas, n'oubliez pas que si vous ne définissez pas de constructeur, le compilateur en générera automatiquement un pour vous (celui-ci est public, n'a pas d'argument et ne fait rien).

143
jfpoilpret

Oui, il peut avoir un constructeur et il est défini et se comporte comme tout constructeur de toute autre classe. Sauf que les classes abstraites ne peuvent pas être directement instanciées, seulement étendues, l'utilisation est donc toujours du constructeur de la sous-classe.

52
Lawrence Dol

Oui ! Les classes abstraites peuvent avoir des constructeurs !

Oui, lorsque nous définissons une classe comme étant une classe abstraite, elle ne peut pas être instanciée, mais cela ne signifie pas qu'une classe abstraite ne peut pas avoir de constructeur. Chaque classe abstraite doit avoir une sous-classe concrète qui implémentera les méthodes abstraites de cette classe abstraite.

Lorsque nous créons un objet d'une sous-classe, tous les constructeurs de l'arbre d'héritage correspondant sont appelés dans une approche de haut en bas. Le même cas s'applique aux classes abstraites. Bien que nous ne puissions pas créer un objet d'une classe abstraite, lorsque nous créons un objet d'une classe concrète et d'une sous-classe de la classe abstraite, le constructeur de la classe abstraite est automatiquement appelé. Nous pouvons donc avoir un constructeur dans les classes abstraites.

Remarque: Une classe non abstraite ne peut pas avoir de méthodes abstraites, mais une classe abstraite peut avoir une méthode non abstraite. La raison est semblable à celle des constructeurs, la différence étant au lieu d'être invoquée automatiquement, nous pouvons appeler super (). De plus, il n’ya rien de comparable à un constructeur abstrait car cela n’a aucun sens.

33
Aniket Thakur

Non seulement ça peut, mais ça le fait toujours. Si vous n'en spécifiez pas, il possède un constructeur par défaut no arg, comme toute autre classe. En fait, TOUTES les classes, y compris les classes imbriquées et anonymes, auront un constructeur par défaut si aucun n’est spécifié (dans le cas des classes anonymes, il est impossible de le spécifier, vous obtiendrez donc toujours le constructeur par défaut).

Un bon exemple de classe abstraite ayant un constructeur est le Calendar class. Vous obtenez un objet Calendar en appelant Calendar.getInstance (), mais il possède également des constructeurs protégés. La raison pour laquelle ses constructeurs sont protégés est que seules ses sous-classes peuvent les appeler (ou des classes du même package, mais étant donné qu'elles sont abstraites, cela ne s'applique pas). GregorianCalendar est un exemple de classe qui étend le calendrier.

13
MattC

Une classe abstraite peut avoir un constructeur MAIS vous ne pouvez pas créer un objet de classe abstraite alors comment utilisez-vous ce constructeur?

Le fait est que lorsque vous héritez de cette classe abstraite de votre sous-classe, vous pouvez transmettre des valeurs à son constructeur (abstrait) via la méthode super (valeur) de votre sous-classe, sans que vous n'héritiez d'un constructeur. 

si vous utilisez super, vous pouvez passer des valeurs dans un constructeur de la classe abstraite et, autant que je m'en souvienne, il doit s'agir de la première instruction de votre méthode ou de votre constructeur. 

6
Alok

Oui, les constructeurs de classes abstraites sont généralement utilisés pour les super-appels d'événements d'initialisation communs à toutes les sous-classes.

5
Jacob

Bien qu'il y ait beaucoup de bonnes réponses, je voudrais donner mes 2 centimes.

Constructeur NE CONSTRUISE PAS L’OBJET . Il est utilisé pour initialiser un objet.

Oui, une classe abstraite a toujours un constructeur. Si vous ne définissez pas votre propre constructeur, le compilateur attribuera un constructeur par défaut à la classe abstraite . 

Une classe abstraite (à la différence de l'interface) peut avoir des champs non finaux non statiques qui nécessitent une initialisation. Pour cela, vous pouvez écrire votre propre constructeur dans la classe abstraite. Mais dans ce cas, il n'y aura pas de constructeur par défaut.

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

Soyez prudent lorsque vous étendez au-dessus de la classe abstraite, vous devez explicitement appeler super depuis chaque constructeur. La première ligne de tout constructeur appelle super (). si vous n'appelez pas explicitement super (), Java le fera pour vous . Le code ci-dessous ne compilera pas:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

Vous devez l'utiliser comme exemple ci-dessous:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}
4
Harshil

Bien sûr, la classe abstraite peut avoir un constructeur. Généralement, le constructeur de la classe est utilisé pour initialiser les champs. Si vous souhaitez initialiser certains champs de la classe abstraite avant l'instanciation d'une classe enfant, vous devez fournir un constructeur pour une classe abstraite. Un constructeur de classe abstraite peut également être utilisé pour exécuter du code pertinent pour chaque classe enfant. Cela empêche la duplication de code.

Nous ne pouvons pas créer une instance d'une classe abstraite, mais nous pouvons créer des instances de classes dérivées de la classe abstraite. Ainsi, lorsqu'une instance de classe dérivée est créée, le constructeur de la classe abstraite parent est automatiquement appelé.

Référence: Cet article

3
Raj Baral

Considère ceci:

abstract class Product { 
    int value;
    public Product( int val ) {
        value= val;
    }
    abstract public int multiply();
}

class TimesTwo extends Product {
    public int mutiply() {
       return value * 2;
    }
}

La super-classe est abstraite et possède un constructeur.

2
S.Lott

Dans une classe concrète, la déclaration d'un constructeur pour un type concret Fnord expose effectivement deux choses:

  • Un moyen par lequel le code peut demander la création d'une instance de Fnord

  • Un moyen par lequel une instance d'un type dérivé de Fnord en construction peut demander l'initialisation de toutes les caractéristiques de la classe de base.

Il devrait peut-être exister un moyen de contrôler ces deux capacités séparément, mais pour chaque type concret, une définition unique les autorisera. Bien que la première capacité ne soit pas significative pour une classe abstraite, la seconde capacité l'est tout autant pour une classe abstraite qu'elle ne le serait pour toute autre classe. Par conséquent, sa déclaration est tout aussi nécessaire et utile.

2
supercat

oui, ça l'est. Et un constructeur de classe abstraite est appelé lorsqu’une instance d’une classe héritée est créée. Par exemple, voici un programme Java valide.

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

Ceci est la sortie du code ci-dessus,

Constructeur de base appelé Constructeur dérivé appelé

références: entrez la description du lien ici

2
chamzz.dot

Pour réaliser le chaînage des constructeurs, la classe abstraite aura un constructeur . Le compilateur conserve l'instruction Super () à l'intérieur du constructeur de la sous-classe, qui appellera le constructeur de la superclasse. S'il n'y avait pas de constructeur pour les classes abstraites, les règles Java sont violées et nous ne pouvons pas réaliser de chaînage de constructeur.

1
Anilkumar K S

Oui, les classes abstraites peuvent avoir des constructeurs!  

Voici un exemple d'utilisation de constructeur en classe abstraite:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

Donc, je pense que vous avez la réponse.

1
Ketan G

Oui, une classe abstraite peut avoir un constructeur. Vous pouvez surcharger autant de constructeurs que vous le souhaitez dans une classe abstraite. Ces sous-traitants peuvent être utilisés pour initialiser l’état initial de la classe d’objets étendant la classe abstraite. Comme nous le savons, nous ne pouvons pas créer un objet d'une classe abstraite, car les objets sont créés par les "nouveaux" mots-clés et non par les constructeurs ... ils sont là pour initialiser l'état de la sous-classe Objets.

1
Shubham Soni

La classe abstraite peut avoir un constructeur bien qu'il ne puisse pas être instancié. Mais le constructeur défini dans une classe abstraite peut être utilisé pour l'instanciation d'une classe concrète de cette classe abstraite. Vérifiez JLS :

C'est une erreur de compilation si l'on tente de créer une instance d'une classe abstraite à l'aide d'une création d'instance de classe expression.

Une sous-classe d'une classe abstraite qui n'est pas abstraite peut être instancié, entraînant l'exécution d'un constructeur pour le classe abstraite et, par conséquent, l'exécution des initialiseurs de champ par exemple, les variables de cette classe.

1
i_am_zero

Comme décrit par javafuns ici , voici un exemple:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}
1
jaideep

Étant donné qu'une classe abstraite peut avoir des variables de tous les modificateurs d'accès, elles doivent être initialisées aux valeurs par défaut, de sorte qu'un constructeur est nécessaire . Lorsque vous instanciez la classe enfant, le constructeur d'une classe abstraite est appelé et sont initialisés.

Au contraire, un interface ne contient que des variables constantes, ce qui signifie qu'elles sont déjà initialisées. Donc, l'interface n'a pas besoin de constructeur.

1
Arun Raaj

Le but du constructeur dans une classe est utilisé pour initialiser des champs mais pas pour "construire des objets". Lorsque vous essayez de créer une nouvelle instance d'une SuperClass abstraite, le compilateur vous renvoie une erreur. Cependant, nous pouvons hériter d'une classe abstraite Employee et utiliser son constructeur en définissant ses variables Voir l'exemple ci-dessous

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}
0
karto

Oui, vous pouvez sûrement en ajouter un, comme cela a déjà été mentionné pour l’initialisation des variables de la classe Abstract . MAIS si vous n’en déclarez pas explicitement une, elle a néanmoins un constructeur implicite pour "Constructor Chaining". 

0
Kedar Parikh