C'est possible, mais pas de la manière dont vous l'envisagez.
Vous devez ajouter un constructeur sans arguments à la classe de base et c'est tout !
public abstract class A {
private String name;
public A(){
this.name = getName();
}
public abstract String getName();
public String toString(){
return "simple class name: " + this.getClass().getSimpleName() + " name:\"" + this.name + "\"";
}
}
class B extends A {
public String getName(){
return "my name is B";
}
public static void main( String [] args ) {
System.out.println( new C() );
}
}
class C extends A {
public String getName() {
return "Zee";
}
}
Lorsque vous n'ajoutez pas de constructeur ( any ) à une classe, le compilateur ajoute le contructeur no arg par défaut pour vous.
Lorsque le defualt no arg appelle super() ; et puisque vous ne l'avez pas dans la super classe vous obtenez ce message d'erreur.
C'est à peu près la question qu'il se pose.
Maintenant, en élargissant la réponse :
Savez-vous que la création d'une sous-classe (comportement) pour spécifier une valeur différente (données) n'a pas de sens ? J'espère que vous le savez.
Si la seule chose qui change est le "nom", alors une seule classe paramétrée est suffisante !
Donc tu n'as pas besoin de ça :
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
o
MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
Quand tu pourras écrire ça :
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
Si je devais modifier la signature de la méthode du constructeur de la BaseClass, je devrais modifier toutes les sous-classes.
C'est pourquoi l'héritage est l'artefact qui crée un couplage élevé, ce qui est indésirable dans les systèmes OO. Il devrait être évité et peut-être remplacé par la composition.
Réfléchissez si vous en avez vraiment besoin comme sous-classe. C'est pourquoi vous voyez très souvent des interfaces utilisées comme insted :
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
Ici, B et C auraient pu hériter de A, ce qui aurait créé un couplage très ÉLEVÉ entre elles, 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 voulez réutiliser le comportement, cela ne fonctionnera pas.
1 votes
S'il vous plaît, laissez le constructeur 'redondant' ! Il préserve la lisibilité de votre code et tous les IDE modernes peuvent le créer automatiquement, il vous suffit donc de saisir un raccourci.
3 votes
En relisant ma propre question un an plus tard, je me suis rendu compte que j'aurais pu supprimer les constructeurs (y compris dans la classe de base) comme l'a suggéré Matt B, et utiliser une méthode de fabrique statique pour construire les instances.