Laden...

Bei eigener Ordner-Klasse den Root-Ordner speziell oder gar in eigener Klasse behandeln

Erstellt von Palladin007 vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.754 Views
Thema geschlossen
Hinweis von herbivore vor 11 Jahren

Der Originaltitel war: "Aktuelle Referenz allgemein so ändern, dass sie nur noch als Referenz der Oberklasse erkannt wird"

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 11 Jahren
Bei eigener Ordner-Klasse den Root-Ordner speziell oder gar in eigener Klasse behandeln

Moin

Ich habe zwei Klassen, die eine erbt von der anderen. Kurzes Mini-Beispiel:

        class OberKlasse
        {
            public int Zahl1 { get; set; }
            public OberKlasse(int Zahl1)
            {
                this.Zahl1 = Zahl1;
            }
        }
        class UnterKlasse:OberKlasse
        {
            public int Zahl2 { get; set; }
            public UnterKlasse(int Zahl1, int Zahl2)
                : base(Zahl1)
            {
                this.Zahl2 = Zahl2;
            }
        }

Ich möchte nun eine Methode in der Klasse Unterklasse anbieten, die die aktuelle Referenz in eine Referenz der Klasse Oberklasse konvertiert.

Ich möchte damit bezwecken, dass die Referenz nach der Konvertierung nur noch die Methoden und Eigenschaften der Oberklasse nutzt und nicht die Überschriebenen Methoden und Eigenschaften der Unterklasse.

Das ganze sollte im Ramen der aktuellen Referenz funktionieren, da Diese auch mit anderen Referenzen in Verbindung steht.

Es ist egal, dass danach die überschriebenen Methoden und zusätzliche Eigenschaften der Unterklasse nicht mehr verfügbar sind, das will ich ja so.

Wenn das so möglich ist, könnte ich damit den Umweg umgehen, eine komplett neue Referenz der Oberklasse, nur mit den Daten der Unterklasse, zu erstellen und jede Beziehung zu dieser Referenz anzupassen.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

W
872 Beiträge seit 2005
vor 11 Jahren

Du solltest mit Interfaces arbeiten und Deine Instanzen sollten ein Interface implementieren, nicht die konkrete Klasse, dann sollte das kein Problem sein...
Wenn eine Referenz zu dem Untertyp gehoert, dann kannst Du die Referenz nicht mehr anpassen...

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 11 Jahren

Ich arbeite mit einem Interface. Die Oberklasse leitet davon ab.
Die Unterklasse ist nur eine spezielle Form der Oberklasse.
Sie tut im Prinzip das selbe, nur etwas anders, daher muss das eine Klasse bleiben.

Nagut, wenns dann nicht geht, muss ich wohl doch alle verknüpften Elemente durch gehen und einzeln die Referenz mit einer Neuen der Oberklasse mit den selben Elementen überschreiben.

Trotzdem Danke, dann brauch ich nicht mehr suchen^^

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

849 Beiträge seit 2006
vor 11 Jahren

Ich habe Dich zwar nicht ganz verstanden was Du damit bezwecken willst, aber schau Dir mal das new Schlüsselwort an (nicht das zum instanzieren einer Klasse, sondern das zum überdecken von Methoden)

Aber so geschätzt bei 90% der fälle ist das die falsche herangehensweise. Ist auf jeden Fall mit vorsicht zu geniessen. Weil ((Oberklasse)this).ÜberdeckteMethode() würde die der Obeklasse ausführen und this.ÜberdeckteMethode() die der Unterklasse. Immer angenommen wir befinden uns gerade in der Unterklasse.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 11 Jahren

Ok, um das Projekt etwas näher zu beschreiben:

Ich hab mir vorgenommen, eine virtuelle Ordnerstruktur zu bauen.
Die kann dann beliebig erweitert werden, für Datei-Verwaltung, ein kompletter Dateimanager, etc.
Ich werde mir das erst einmal so bauen, dass ich damit eine möglichst einfache Ressourcen-Verwaltung habe. Mit den Ressourcen-Dateien kann ich nicht viel anfangen, da das Hinzufügen und Entfernen nicht zur Laufzeit möglich ist (so hat man es mir zumindest gesagt).
Das ganze soll dann die Möglichkeit bieten, die Ressource nur noch mit ein oder zwei Zeilen zu verwenden, ohne sich um die eigentlichen Dateien kümmern zu müssen.

Dazu habe ich ein Interface, das einige allgemeine Dinge, wie Kopieren, oder der Name, bereit stellt.
Die Klassen für eine Datei und einen Ordner erben beide davon.

Nun liegt jedes Element in einem Ordner und wenn man das schön weiter denkt, kommt man irgendwann bei einem Ordner an, der in keinem Ordner mehr liegt. Das ist dann mein Parent-Ordner, in dem alles liegt, alle Dateien und Ordner.

Nun hab ich mir die Frage gestellt, wie ich diesen Parent-Ordner beschreibe. Ich könnte es zwar so machen, dass ich dann einfach die Eigenschaft Parent auf null setze und überall überprüfe, ob das null ist, wenn ich wissen will, ob das der Parent-Ordner ist.
Das finde ich aber ziemlich unpraktisch, daher habe ich eine weitere Klasse erstellt, die von der Klasse erbt, die die Ordner bereit stellt.
Der neuen Parent-Klasse füge ich dann noch die Eigenschaft PhysicalPath hinzu, die den eigentlichen Windows-Pfad beschreibt und einige Methoden werden überschrieben, da sie in der Position des Parent-Ordners eine andere Auswirkung haben. Das erspart mir die unnötig komplizierten Methoden, die je nach Art des Ordners eine andere Reaktion zeigen.

Nun soll aber auch dieser Parent-Ordner normal kopiert werden. Das in einen anderen Windows-Pfad zu legen ist kein Ding, aber ich will es ermöglichen, diesen Ordner auch in einen Ordner zu legen, der in einem weiteren Parent-Ordner, also einer anderen Struktur liegt.
Der aktuelle Ordner kann aber nicht einfach kopiert werden, weil dann die PhysicalPath-Eigenschaft und die ganzen überschriebenen Methoden eine falsche Wirkungsweise hätten. Daher möchte ich sagen, dass einfach kopiert wird, aber gleichzeitig dann nur noch die Methoden der normalen Ordner-Klasse verwendet werden.

Ich könnte zwar new nutzen, finde das aber nicht wirklich gut und nicht entsprechend der objektorientierten Programmierung.
Außerdem würde das Probleme geben, da sowohl der Parent-Ordner, als auch alle anderen Ordner einfach nur Ordner sind. Da soll es im Programm auch nur dann Unterschiede geben, wenn sie wirklich da sind. Soll heißen, ich werde den Parent-Ordner nicht als Referenz dieser Klasse hin und her schieben und verarbeiten, sondern als Referenz der Oberklasse. Das fordert aber, dass die Oberklasse die Methoden der Unterklasse verwendet und das ist mit new leider nicht gegeben.

Ich hoffe, mein Problem ist halbwegs klar geworden. Hab schon öfters versucht, es zu erklären, bin aber jedes mal auf Schwierigkeiten gestoßen, weil ich es irgendwie nie schaffe, mein Vorhaben genau so zu beschreiben, wie ich es mir tatsächlich vorstelle.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

C
2.121 Beiträge seit 2010
vor 11 Jahren

Der aktuelle Ordner kann aber nicht einfach kopiert werden, weil dann die PhysicalPath-Eigenschaft und die ganzen überschriebenen Methoden eine falsche Wirkungsweise hätten.

Warum hätten sie das? Ist da wirklich so ein großer Unterschied zwischen den Ordnern, außer dass einer keinen Parent mehr hat und die anderen schon?
Ich würde das genauso abbilden wie du es mit dem Parent beschreibst, denn das sehe ich als die realistischste Modellierung an.

Ich habs aber auch nicht wirklich verstanden muss ich zugeben.
Wärs so schlimm wenn du einfach ein if (IsRootDirectory) in eine Methode einbaust? Andernfalls müsstest du ja zwei Methoden ausprogrammieren, Code sparst du dir also nicht wirklich damit.

Beschreib mal was du da als Unterschiede siehst, vielleicht gibts ja noch eine Lösung.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 11 Jahren

Naja, als offensichtlichstes Beispiel wäre die Delete-Methode.
Die löscht den gesamten Inhalt und die eigene Referenz aus dem Parent-Ordner.

Wenn der Parent-Ordner aber gelöscht wird, gibt es erst mal die Delete-Methode der base (ohne das Entfernen aus dem natürlich nicht vorhandenen Parent-Ordner) und dann noch zusätzlich die Änderung auf der Festplatte, die eingebaut werden muss. Ob es nun eine physikalische Datei-Unterstützung gibt, oder nicht.

Dann noch der Ordner, der einen String-Pfad kreieren soll.
Der kann dann nicht mit der üblichen Vorgehensweise den Pfad auslesen, wie alle anderen Ordner, sondern der liest den Pfad der Anwendung aus und gibt den mit einem Trennzeichen aus.

Außerdem wäre die Überprüfung, ob das nun der Parent-Ordner ist, ganz simpel mit einem

return this is ParentDirectory;

gelöst, wo ich sonst mir überlegen muss, wie ich in der Referenz des Parent-Ordners wirklich absolut idiotensicher und fehlerfrei fest legen kann, dass das auch ein Parent-Ordner ist. Wenn ich das mit einer abgeleiteten Klasse mache, wäre das ganz einfach und ich kann die physikalischen Pfad sogar als extra Eigenschaft zur Verfügung stellen, denn in allen anderen Ordnern würde die keinen Sinn machen.

Zum Verständnis:
Im Prinzip ist das ein Dateimanager, der nur noch nicht mit Dateien arbeiten kann, sondern die Dateien und Ordner mittels Name in eine Datenbank einordnet. Veränderungen finden dann nur in der Datenbank statt, außer man sagt, dass sie physikalisch durch geführt werden soll, oder man leitet die Klassen ab. Je nachdem, wie ich es dann mache. Ich hab im Moment noch vor, abzuleiten.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

C
258 Beiträge seit 2011
vor 11 Jahren

Warum brauchst du eine Methode um den typ deiner Referenz variable zu ändern das kannst du doch machen wann immer du willst

Oberklasse referenzOberklasse = referenzUnterklasse;

Und schon kannst du mit referenzOberklasse nur die Base Methoden aufrufen obwohl es sich um ein Element der Unterklasse handelt.

Jedoch halte ich deinen Ansatz für falsch (bitte nicht angegriffen fühlen), für mich klingt es logisch die unterscheidung des Parent Ordners mit Parent == null zu machen.
So wie auch (glaube ich) in jedem baum das Root object mit Parent == null zu finden ist.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Console32,

Und schon kannst du mit referenzOberklasse nur die Base Methoden aufrufen obwohl es sich um ein Element der Unterklasse handelt.

genauer: nur Methoden bzw. Member, die schon in der Oberklasse vorhanden/definiert sind. Wenn diese aber virtual sind - was sie sein sollten, wenn ihre Funktionalität in der Unterklasse geändert wird -, dann wird aber trotzdem die Methode der Unterklasse aufgerufen (dynamische Bindung).

Hallo Palladin007,

Ich könnte zwar new nutzen, finde das aber nicht wirklich gut und nicht entsprechend der objektorientierten Programmierung.

korrekt, new ist eine Krankheit und nur in wenigen Spezialfällen wirklich sinnvoll nutzbar. Das haben wir schon mehrfach im Forum diskutiert.

Anderseits ist deine Idee, die "Aktuelle Referenz allgemein so ändern, dass sie nur noch als Referenz der Oberklasse erkannt wird" auch nicht objektorientiert. Ein Objekt bekommt seinen Typ bei der Erstellung und behält diesen die gesamte Lebensdauer. Er kann nachträglich nicht geändert werden.

Zwar kann man eine Referenz eines Objekts an eine Variable vom Typ der Oberklasse zuweisen, wie das Console32 gezeigt hat, aber es gilt dann, was ich dazu schon gesagt habe. Nützt also nur was, wenn man new statt override verwendet und das ist eben auch nicht objektorientiert.

Wie man es dreht, ein Objekt behält die ganze Lebensdauer seinen Typ und wenn die Methoden oo-konform überschrieben wurden, dann werden auch über eine Variable vom Typ der Oberklasse weiter und korrekterweise die Methoden der Unterklasse aufgerufen.

Bis hier hin, sind das auf jeden Fall es Grundlagen, siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

Die Folgerung für deinen konkreten Anwendungsfall liegt dann aber auch nicht mehr fern. Wie schon von den anderen gesagt ist es üblich, einfach eine Abfrage auf Parent != null oder IsRoot in den Code der Ordnerklasse einzubauen und dann entsprechend unterschiedlich zu reagieren.

Solltest du die besondere Funktionalität des Wurzelknotens wirklich unbedingt in einer eigenen Klasse haben wollten, musst du dafür eine _Unter_klasse der normalen Ordnerklasse schreiben. Und dann auch schon bei der Erzeugung der Objekte darauf achten, dass du für den Wurzelknoten ein Objekt dieser Unterklasse erzeugst.

herbivore

Thema geschlossen