NEWS
Abgeleitete Klassen
-
@haus-automatisierung sagte in Abgeleitete Klassen:
@wolfgangfb sagte in Abgeleitete Klassen:
Je nachdem in welcher Reihenfolge ich die Abgeleiteten Klassen erzeuge kommt die Fehlermeldung "Bla1" bzw. "Bla2" is not a function. Jede abgeleitete Klasse für sich alleine geht.
Logisch, weil Du ja oben eine Art Singleton-Pattern gebaut hast. Was soll der Teil mit der Prüfung auf
.instance
?Ähm, das ist meiner Meinung nach genau die Singleton Implementierung. Wenn noch keine Instanz erzeugt ist wird eine erzeugt, ansonsten wir die Einzige bisher verwendet Instanz verwendet. So habe ich bisher Singleton verstanden.
-
@haus-automatisierung sagte in Abgeleitete Klassen:
Eher so:
class BasisFunktionsKlasse{ constructor(){ this.pfad = "Hallo"; this.Logfunktion("BasisFunktionsKlasse erzeugt 1"); this.Datenpunkte = 1; } Logfunktion(text) { console.log(`Exportierter Text: ${text} ${this.pfad}`)}; } } class AbgeleiteteUnterklasse1 extends BasisFunktionsKlasse{ Bla1(){ console.log("Bla1"); } constructor() { super(); // Aufruf des Constructors der Basisfunktionsklasse this.Logfunktion("Abgeleitete UnterKlasse1 erzeugt " + this.Datenpunkte); this.Bla1(); } } class AbgeleiteteUnterklasse2 extends BasisFunktionsKlasse{ Bla2(){ console.log("Bla2"); } constructor() { super(); // Aufruf des Constructors der Basisfunktionsklasse this.Logfunktion("Abgeleitete UnterKlasse2 erzeugt " + this.Datenpunkte); this.Bla2(); } } const AbgeleiteteKlasse2 = new AbgeleiteteUnterklasse2(); const AbgeleiteteKlasse1 = new AbgeleiteteUnterklasse1();
Das ist aber nicht Siongleton, jede Unterklasse erhält hier eine eigene Instanz der Basisklasse. Lass mal Unterklasse2 den Wert von Datenpunnt ändern, Unterklasse1 bekommt davon nichts mit.
-
@wolfgangfb Das ist ja der Sinn von Klassen?! Definiere nochmal deine Anforderung genauer.
Singleton bedeutet, dass es von einer Klasse nur ein Objekt geben darf und man nicht beliebig viele erzeugen kann. Mehr nicht. Mit Vererbung hat das erstmal nichts zu tun.
Dein Problem ist BasisFunktionsKlasse.instance
Das ist global und nicht pro Objekt/Klasse. Daher entscheidet die Reihenfolge, ob darin ein Objekt der ersten oder zweiten Klasse gespeichert wurde. Dementsprechend gibt es manche Funktionen (der anderen Klasse) dann nicht.Wenn Du möchtest dass jede abgeleitete Klasse ein Singleton ist, dann ist das mit JavaScript nicht so einfach abbildbar. In anderen Programmiersprachen gibt es da elegante Möglichkeiten.
Such mal nach singleton inheritance
-
@haus-automatisierung
Für mich bedeutet Singleton, dass es von einer Klasse nur eine Instanz geben darf (so finde ich das auch überall in den Beschreibungen), das bedeutet aber nicht, dass nicht mehrere Objekte auf diese eine Instnz zugreifen können (das ist ja genau der Sinn des Singleton Design Patterns, nämlich dass sich mehrere Objekte die gleichen Resourcen teilen). Mein Anliegen war zu lernen (mir geht es hier nur ums lernen) wie das ist, wenn eine Klasse von einer Singleton Klasse erbt und dieser Mutterklasse weitere Methoden hinzufügt ob diese zusätzlichen Methoden auch anderen Klassen, die von dieser Klasse erben, verfügbar sind. Das ist wohl nicht der Fall. Was ich immer noch nicht verstehe ist, warum Kindklassen mal eine Funktion hinzufügen können und mal nicht.
Der Ansatz über Klasse.instance ist laut Internet neben der Static Methode wohl ein üblicher Ansatz in JS eine Singleton Instanz zu erzeugen. Mir ist bewusst, dass es in JS keine 100%ige Singleton Variante einer Klasse wie z.B. in Java geben kann. Deswegen mein "Experiment" die Grenzen des Singleton Designs in Javascript zu verstehen. -
@wolfgangfb Das habe ich doch oben versucht zu erklären. Du speicherst eine Instanz/ein Objekt in die Eigenschaft .instance.
Und da kann nur ein Objekt enthalten sein. Je nachdem was Du zuerst aufrufst, ist das entweder ein Objekt der ersten oder der zweiten Klasse. Das ist vom Konzept einfach so nicht lösbar wie Du dir das vorstellst. Du müsstest das Singleton Pattern also im Construktor von jeder abgeleiteten Klasse abbilden.
Dann kann es von jeder dieser Klassen nur ein Objekt geben. Aber da sehe ich den Mehrwert gegenüber einer Funktionssammlung (ohne Klasse) nicht. Daher die Frage nach dem konkreten Anwendungsfall und was Du vor hast
-
@haus-automatisierung
Danke erstmal für die Erklärungen. Wie Du ja schon bemerkt hast habe ich noch ein paar Verständnisprobleme. Mein Gedanke war der: Wenn eine Klasse Singleton ist, sprich bei der Erzeugung sichergestellt ist, dass es nur eine Instnaz davon gibt, und eine andere Klasse von dieser Klasse erbt, dass die Unterklassen die Methoden von der Basisklassen erben und weil es von der Basisklasse ja nur eine Instanz gibt alle Unterklassen auf die gleiche Instanz der Basisklasse zugreifen. Dann hätte ich erwartet, dass die Unterklassen zusätzliche Methoden erzeugen können und meine Frage war eben an der Stelle, ob diese zusätzlichen Methoden an die Basisklasse (von der es ja nur eine Instanz gibt) angefügt werden (dann hätte nach meinem Verständnis jede abgeleitete Klasseninstanz auch diese Methoden) oder ob diese zusätzlichen Methoden auf die abgeleitete Klasse beschränkt bleiben (dann verstehe ich nicht, warum nicht 2 abgeleitete Klassen 2 verschiedene zusätzliche Methoden haben dürfen. Einen konkreten Anwendungsfall habe ich nicht, mir geht es erst mal darum das ganze zu verstehen. -
@wolfgangfb sagte in Abgeleitete Klassen:
@haus-automatisierung
Danke erstmal für die Erklärungen. Wie Du ja schon bemerkt hast habe ich noch ein paar Verständnisprobleme. Mein Gedanke war der: Wenn eine Klasse Singleton ist, sprich bei der Erzeugung sichergestellt ist, dass es nur eine Instnaz davon gibt, und eine andere Klasse von dieser Klasse erbt, dass die Unterklassen die Methoden von der Basisklassen erbenDas ist ja auch alles richtig. Aber Du machst ja deutlich mehr. Die Frage ist ja: Singleton von was? Von der Basisklasse? Geht.
Aber wenn nun eine weitere Klasse von dieser erbt: Was ist der gewünschte Effekt? Dass es nur je eine Instanz von der Basisklasse + nur eine Instanz von der zweiten Klasse geben darf? Da fängt es ja schon an.
Deswegen kann man in anderen Programmiersprachen den Constructor private setzen oder eine Klasse als final definieren, damit man damit nicht machen kann, was man möchte.
So wie Du es gerade machst ist es jedenfalls total falsch, weil der Constructor der anderen Klasse ja ggf ein Objekt einer ganz anderen Klasse zurückgibt. Und daher auch dein Problem.
Lies dich mal in Polymorphie ein. In JavaScript sind die Möglichkeiten da etwas eingeschränkt. TypeScript kann da schon mehr und kennt auch mehr Schlüsselwörter.
-
@wolfgangfb Du schriebst ja selber ..
Für mich bedeutet Singleton, dass es von einer Klasse nur eine Instanz geben darf (so finde ich das auch überall in den Beschreibungen), das bedeutet aber nicht, dass nicht mehrere Objekte auf diese eine Instnz zugreifen können (das ist ja genau der Sinn des Singleton Design Patterns, nämlich dass sich mehrere Objekte die gleichen Resourcen teilen).
Wenn nun Instanzen von zwei Klassen auf die Methoden der Singleton-Klasse zugreifen wollen, sollte man das meiner Meinung nach nicht über irgendwelche Vererbungsmechanismen machen... Bei mir würden beide Klassen über eine Referenz auf die Instanz der Singleton-Klasse arbeiten...
Im Konstruktor der beiden Klassen wird sich umgeschaut, ob die Instanzierung der Singleton-Klasse schon erfolgt ist, sonst wird das dort erledigt ...
-
Als erstes muss ich sagen das das von dir erwartete Verhalten nicht einmal in c++ existiert.
JavaScript selbst ist keine echte objektorientierte Programmiersprache.Klassendefinitionen sind nur templates
Wenn das Objekt erzeugt wird wird das anhand den templates gemacht. Wenn die per extend aufeinander aufbauen, werden die der Reihe nach durch kopiert bis das endgültige Objekt angelegt wurde.
Bei einem singleton existiert exakt nur ein Objekt. Wird versucht weitere Objekte neu anzulegen dann wird immer das ursprünglich angelegte erneut zurückzugeben. Das passiert aber nur auf Basis des angegebenen Typ namens. Also bla1 und dann bla1.
Machst du bla1 und dann bla2 dann ist das ein komplett neues Objekt.
Versuchst du dann danach ein 2. bla2 anzulegen dann erhältst du wieder das erste bla2 zurück.
Wie gesagt real existiert kein Objekt Basislager. Das wird nur in die objektdefinition reinkopiert.Diese Aussage gilt für JavaScript.
Ob die Aussage auch für typescript gilt kann ich nicht genau sagen. Das muss man Mal nachlesen. Aber ich denke das ist identisch.Beschreibe mal warum du ein singleton haben willst, evtl kann man dann dir bessere Typs geben.
Ich persönlich erzeuge singletons nicht über Code im constructor sondern über ein Factory Objekt.
Das fühlt sich für mich besser an und ich muss nicht mit statischen variablen rumhantierenIm 2. Beitrag ist ein Beispiel für den Factory Ansatz
Hier nochmal der belegt für die Objekt Orientierung in JavaScript
To be more precise, JavaScript is a prototype-based Object Oriented Language, which means it doesn't have classes, rather it defines behaviors using a constructor function and then reuses it using the prototype. Note: Even the classes provided by ECMA2015 are objects.
https://www.geeksforgeeks.org/introduction-object-oriented-programming-javascript/amp/
-
Es geht mir darum, dass man die Finger vom "Erben" von einer Klasse lassen sollte, die als Singleton designt ist ...
Wenn man eine Singleton-Klasse designt hat, die Rechtecke und Kreise verwalten soll, und man ein Klasse braucht, die nur die Rechtecke verwaltet, sollte sie das Singleton-Objekt referenzieren, und sich dessen Methoden bedienen, aber nicht von ihr abgeleitet sein ...