Den Konstruktor kann man aufrufen, indem man folgendes schreibt:
Sub new(someParameters), Oberklasse(Parameter zum weiterreichen)
End Sub
Genau so habe ich es schon mehrfach gemacht. Dachte ursprünglich auch mal, dass das nicht geht...
Ich sehe das nicht als Workaround, sondern als Lösung, wenn er in einer Unterklasse mehr Parameter im Konstruktor braucht. Anders geht es gar nicht, denn du erweiterst ja im Prinzip durch den neuen Paramater die Signatur von new und rufst dann mit dem Zusatz den Konstruktor der Oberklasse auf.
Selbst in Java ist das nicht anders als in LS. Dort würde man auch erst alle Parameter hinschreiben und dann die für die Oberklasse wichtigen per super()-Aufruf an die Vaterklasse weiterleiten. Beispiel aus Java:
public class A
public A(int i) {
//Do something
}
//methods etc
}
public class B extends A {
public B (int i, int j) {
super(i);
//Do something
}
//methods etc
}
In LS und Java wirst du ja auch vom Compiler gezwungen, einen expliziten Konstruktor zu schreiben, wenn der Konstruktor der Superklasse Paramter erwartet. Zudem muss der super-Aufruf im Konstruktor immer als erstes erfolgen. Damit finde ich sogar fast die Lösung von LS eleganter, denn dort kann man den Aufruf des Konstruktors der Oberklasse nur weglassen aber nicht an die falsche Stelle schreiben, da man ja schon von der Grammatik her dazu gezwungen wird.
Zudem hat überschreiben nichts mit den Parametern einer Operation zu tun, sondern das ist ein überladen einer Operation.
Wenn du denn Kontruktor in der erweiterten Klasse überschreibst, wird der von der Basisklasse nicht mehr ausgeführt.
Nein. In jeder mir bekannten OO Sprache mit Vererbung werden grundsätzlich die Konstruktoren der Klassen von denen geerbt wird beim Aufruf eines Konstruktors der erbenden Klasse aufgerufen. Das macht auch Sinn, weil ein Objekt der erbenden Klasse in einer isA-Beziehung zur Klasse von der die erbende Klasse erbt steht. ;D
Und das ist ein grundlegender Unterschied im Verhalten von Konstruktoren im Gegensatz normalen Methoden.
Ich seh die Implementierung in LotusScript hier auch nicht als Workaround, sondern als konsistent zu grundlegenden OO-Prinzipien.
Beispiel:
Die Klasse Hund erbt von Säugetier
Jedes Säugetier (also auch Hund) hat ein property blutTemperatur.
Das property blutTemperatur soll während der ganzen Lebenszeit des Objektes einen sinnvollen Wert haben.
Also legt der Entwickler fest, dass es im Konstruktor von Säugetier gesetzt wird.
In Java Syntax
class Säugetier {
private double blutTemp;
// Konstruktor
public Säugetier(int blutTemp) {
this.blutTemp = blutTemp;
}
public double getBlutTemp() {
return blutTemp;
}
}
class Hund extends Säugetier {
private int bellenLautstärke;
public Hund(double blutTemp, bellenLautstärke) {
super(blutTemp);
this.bellenLautstärke = bellenLautstärke;
}
public getBellenLautstärke() {
return bellenLautstärke;
}
}
In konstruktoren werden bestimmte properties gesetzt, die zum state des Objektes gehören.
Der Hund ist ein Säugetier. Also muß hier konkret auch der Wert blutTemp gesetzt sein.
Ein konsistenter state wird am einfachsten dadurch gewährleistet, dass Konstruktoren der Klassen der gesamten Vererbungshierarchie aufgerufen werden und so ist das auch in der Praxis.
Ohne den super(blutTemperatur) im Hund-Konstruktor würde das in Java nicht kompilieren und zwar mit einer ähnlichen Fehlermeldung wie LotusScript. Manchmal ist kein super()-Aufruf da. Dann wird vom Java-Kompiler automatisch das statement super() eingesetzt, ohne dass man das sieht. Es bedeutet, dass ein Konstruktor ohne Parameter der Klassen von der geerbt wird aufgerufen wird. Der ist aber in Säugetier nicht vorhanden.
Manche Klassen haben überhaupt keinen sichtbaren Konstruktor. Da fügt der KOmpiler dann aber einen impliziten leeren Konstruktor ohne Argumente ein. Sobald eine Klasse irgendeinen Konstruktor hat, muss dieser parameterlose Konstruktor explizit im Code vorhanden sein.