J'ai un code Java simple qui ressemble à ceci dans sa structure:
abstract public class BaseClass {
String someString;
public BaseClass(String someString) {
this.someString = someString;
}
abstract public String getName();
}
public class ACSubClass extends BaseClass {
public ASubClass(String someString) {
super(someString);
}
public String getName() {
return "name value for ASubClass";
}
}
J'aurai pas mal de sous-classes de BaseClass
, chacune implémentant la getName()
méthode à sa manière ( modèle de méthode de modèle ).
Cela fonctionne bien, mais je n'aime pas avoir le constructeur redondant dans les sous-classes. C'est plus à taper et c'est difficile à maintenir. Si je devais changer la signature de méthode du BaseClass
constructeur, je devrais changer toutes les sous-classes.
Lorsque je supprime le constructeur des sous-classes, j'obtiens cette erreur de compilation:
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
Ce que j'essaie de faire est-il possible?
Réponses:
Vous obtenez cette erreur car une classe qui n'a pas de constructeur a un constructeur par défaut , qui est sans argument et équivaut au code suivant:
Cependant, puisque votre BaseClass déclare un constructeur (et n'a donc pas le constructeur par défaut, sans argument que le compilateur fournirait autrement), c'est illégal - une classe qui étend BaseClass ne peut pas appeler
super();
car il n'y a pas de constructeur sans argument dans BaseClass.C'est probablement un peu contre-intuitif car vous pourriez penser qu'une sous-classe a automatiquement tout constructeur que possède la classe de base.
Le moyen le plus simple de contourner cela est pour la classe de base de ne pas déclarer de constructeur (et donc d'avoir le constructeur par défaut, no-arg) ou d'avoir un constructeur sans argument déclaré (soit seul, soit à côté de tout autre constructeur). Mais souvent, cette approche ne peut pas être appliquée - car vous avez besoin des arguments passés au constructeur pour construire une instance légitime de la classe.
la source
BaseClass
mais le faire simplement lancer unUnsupportedOperationException
ou quelque chose. Ce n'est pas la meilleure solution (cela suggère à tort que la classe peut supporter un constructeur sans argument), mais c'est la meilleure à laquelle je puisse penser.Pour ceux qui recherchent cette erreur sur Google et arrivent ici: il pourrait y avoir une autre raison de la recevoir. Eclipse donne cette erreur lorsque vous avez une configuration de projet - incompatibilité de configuration du système.
Par exemple, si vous importez un projet Java 1.7 dans Eclipse et que la 1.7 n'est pas correctement configurée, vous obtiendrez cette erreur. Ensuite, vous pouvez aller à
Project - Preference - Java - Compiler
etswitch to 1.6 or earlier
; ou allez dansWindow - Preferences - Java - Installed JREs
et ajoutez / corrigez votre installation JRE 1.7.la source
C'est possible mais pas comme vous l'avez.
Vous devez ajouter un constructeur no-args à la classe de base et c'est tout!
Lorsque vous n'ajoutez pas de constructeur (aucun) à une classe, le compilateur ajoute le constructeur par défaut no arg pour vous.
Quand defualt no arg appelle super (); et comme vous ne l'avez pas dans la super classe, vous obtenez ce message d'erreur.
C'est à peu près la question en soi.
Maintenant, élargissez la réponse:
Etes-vous conscient que la création d'une sous-classe (comportement) pour spécifier une valeur différente (données) n'a aucun sens ?? !!! J'espère que tu vas le faire.
Si la seule chose qui change est le "nom" alors une seule classe paramétrée suffit!
Vous n'avez donc pas besoin de ceci:
ou
Quand vous pouvez écrire ceci:
Eh bien, c'est pourquoi l'héritage est l'artefact qui crée un couplage HIGH, ce qui n'est pas souhaitable dans les systèmes OO. Il devrait être évité et peut-être remplacé par la composition.
Pensez si vous en avez vraiment besoin en tant que sous-classe. C'est pourquoi vous voyez très souvent des interfaces utilisées instées:
Ici, B et C auraient pu hériter de A qui aurait créé un couplage très ÉLEVÉ entre eux, en utilisant des interfaces le couplage est réduit, si A décide qu'il ne sera plus "NameAware" les autres classes ne seront pas cassées.
Bien sûr, si vous souhaitez réutiliser un comportement, cela ne fonctionnera pas.
la source
Vous pouvez également obtenir cette erreur lorsque JRE n'est pas défini. Si tel est le cas, essayez d'ajouter la bibliothèque système JRE à votre projet.
Sous Eclipse IDE:
la source
Une autre façon est d'appeler super () avec l'argument requis comme première instruction dans le constructeur de classe dérivée.
la source
Eclipse donnera cette erreur si vous n'avez pas d'appel au constructeur de super classe comme première instruction dans le constructeur de sous-classe.
la source
Désolé pour le nécropostage, mais j'ai rencontré ce problème aujourd'hui. Pour tous ceux qui sont également confrontés à ce problème - une des raisons possibles - vous n'appelez pas
super
à la première ligne de méthode. Les deuxième, troisième et autres lignes déclenchent cette erreur. L'appel de super devrait être le tout premier appel de votre méthode. Dans ce cas, tout va bien.la source
Vous pouvez résoudre cette erreur en ajoutant un constructeur sans argument à la classe de base (comme indiqué ci-dessous).
À votre santé.
la source
someString
) set et donc va totalement à l'encontre de l'objectif de en tant que constructeur.J'ai eu cette erreur et je l'ai corrigée en supprimant une exception levée à côté de la méthode vers un bloc try / catch
Par exemple: FROM:
À:
la source