Die Initialisierung einer Klasse mit Oberklasse-Initialisierer
Ich habe zwei Klassen, eine Unterklasse der anderen (sagen Animal
und Dog
). Die Oberklasse hat einige Initialisierungen (sagen initAnimal
), die Unterklasse hat einige Initialisierungen (sagen initDog
). Das problem ist, dass es perfecly legal (aus compiler-Sicht) etwas zu tun, wie Dog *adog = [[Dog alloc] initAnimal]
, dh. initialisieren einer Klasse mit Ihrem Oberklasse-Initialisierer. Ich weiß nicht, wie diese, weil die Unterklasse kann zusätzliche Instanz-Variablen, die ich will, um sicherzustellen, werden initialisiert. Ein Blick in die header-Datei löst dieses Problem, aber gibt es eine einfache Möglichkeit, um den compiler-check für mich? Ich habe eine das Gefühl mir fehlt etwas furchtbar offensichtlich, aber ich kann einfach nicht meinen finger auf Sie 🙂
Update: Das initDog
und initAnimal
waren nicht die besten Beispiele. Ich meinte zwei wirklich unterschiedliche Initialisierungen (wie init
für Animal
und initWithFur
für Dog
). Wenn ich wollte, dass jeder Hund zu haben, einige Fell zugewiesen, ich hätte den Pelz Teil der Initialisierung, so dass niemand erwerben könnten, ist ein Hund-Objekt ohne Fell. Aber dann ist es immer noch leicht irrtümlich initialisiert die Instanz mit der Superklasse init
, und dann bin ich abgespritzt.
Danke für die vorgesehenen Initialisierungen, Jason. Es trat nicht zu mir vor, aber ich könnten zu einer überlastung der designierte Initialisierer der Oberklasse und einige vernünftige Standards gibt. Aber ich würde es dennoch lieber, wenn ich irgendwie könnte es illegal zu verwenden, andere Initialisierungen als diejenigen, die von der Klasse selbst – mehr Ideen?
- Okay Zoul, machte ich updates zu meiner Antwort auf die updates zu deiner Frage... es ist ziemlich lange her, aber ich hoffe, es gibt Ihnen einige der Einsichten, die Sie gesucht haben.
- Da dies ein top-Ergebnis.Die Antwort in der modernen XCode können Sie erreichen, dass mit NS_UNAVAILABLE. Siehe: stackoverflow.com/questions/195078/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der Regel in Objective-C erstellen Sie einen designierten Initialisierer, die für jede Klasse und dann Unterklassen verwenden Sie die gleiche Initialisierung. Anstatt also mit initAnimal und initDog, verwenden Sie einfach die init. Der Hund Unterklasse wäre dann zu definieren, Ihre eigenen init-Methode, und rufen den designierten Initialisierung in der übergeordneten Klasse:
Die Sie nicht wirklich haben, um anzugeben, initDog und initAnimal, weil die Klasse deklariert ist auf der rechten Seite der Zuweisung...
Update: ich bin das hinzufügen der folgenden, auf die Antwort zu reflektieren, die zusätzliche Informationen in der Frage
Gibt es eine Reihe von Möglichkeiten, um sicherzustellen, dass Sie in Unterklassen nicht nennen Initialisierungen anderen als Ihrem designierten Initialisierer und die Art und Weise, die Sie letztlich wählen, wird weitgehend auf Ihre gesamte design. Eines der schönen Dinge über Objective-C ist, dass es so flexibel ist. Ich gebe Ihnen zwei Beispiele, um Ihnen den Einstieg.
Ersten, wenn Sie erstellen eine Unterklasse, die eine andere designierte Initialisierer als die übergeordnete Klasse haben, können Sie überlastung der Eltern, die Initialisierung und eine exception werfen. So können Programmierer sofort wissen, dass Sie haben gegen das Protokoll für Ihre Klasse... aber, es sollte erwähnt werden, dass Sie eine sehr guten Grund, dies zu tun, und dass es sein sollte sehr gut dokumentiert werden, dass die Unterklasse kann nicht mit der gleichen Initialisierung wie der Superklasse.
Anderen Weg, es zu tun ist, um Initialisierer mehr wie Ihre original-Beispiel. In diesem Fall könnten Sie ändern das default-init-auf die übergeordnete Klasse immer fehl. Sie könnten dann erstellen Sie ein eigenes Initialisierer für Ihr übergeordneten Klasse und dann stellen Sie sicher, jeder ruft die entsprechende Initialisierung in Unterklassen. In diesem Fall ist offensichtlich komplizierter:
Hier sehen Sie die Schnittstelle und die Implementierung des Tieres und den Hund Klasse. Das Tier ist der designierte top-level-Objekt und daher überschreibt NSObject ist die Implementierung von init. Wer ruft init auf ein Tier oder einen Tierischen die Unterklassen erhalten eine assertion-Fehler, verweisen Sie auf die Dokumentation. Tier definiert auch eine private Initialisierer auf eine private Kategorie. Die private Kategorie bleiben würde, die mit Ihrem code und Unterklassen von Tier nennen würde, diese private-Initialisierung, wenn der Anruf bis zu super. Es ist Zweck ist der Aufruf von init, die auf Tier Oberklasse (NSObject in diesem Fall) und dazu eine generische Initialisierung, die notwendig sein könnten.
Endlich, die erste Zeile in Tier initAnimal Methode ist eine Behauptung, dass der Empfänger tatsächlich ein Tier und nicht eine Unterklasse. Wenn der Empfänger nicht ein Tier, das Programm wird nicht mit einem assertion-Fehler und der Programmierer werden gemäß der Dokumentation.
Dies sind nur zwei Beispiel dafür, wie Sie etwas entwerfen mit Ihren spezifischen Anforderungen. Allerdings würde ich stark schlage vor, Sie betrachten Ihre design-Einschränkungen und sehen, ob Sie wirklich diese Art von design, wie es ist non-standard in der Kakao-und in den meisten OO-design frameworks. Zum Beispiel, können Sie erwägen, verschiedene Tiere root-level-Objekte und nur ein Tier-Protokoll statt, dass alle von den verschiedenen "Tieren" Antworten auf bestimmte Tier-generic-Nachrichten. Auf diese Weise jedes Tier (und echte Unterklassen von Tier) umgehen kann Ihren vorgesehenen Initialisierungen sich selbst und nicht sich verlassen auf Oberklassen Verhalten in solch einer speziellen, nicht-standard-Weise.