Tut Objective-C support-Mixin wie Ruby?
In Ruby gibt es Module, und Sie können eine Klasse erweitern, durch "mischen-in" - Modul.
module MyModule
def printone
print "one"
end
end
class MyClass
include MyModule
end
theOne = MyClass.new
theOne.printone
>> one
In Objective-C, ich finde, dass ich eine Reihe von gemeinsamen Methoden, will ich eine Reihe von Klassen zu "Erben". Welche anderen Möglichkeiten kann ich erreichen, das ohne die Erstellung einer gemeinsamen Klasse und ergeben sich alle aus dem gemeinsamen Unterricht?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bearbeiten: änderungen Hinzugefügt, weil einige Leute das Gefühl, dass ich verantwortlich bin für die Grenzen von Objective-C.
Kurze Antwort: Sie können nicht. Objective-C hat nicht das äquivalent von Ruby Mixins in Verbindung.
Etwas weniger kurze Antwort: Objective-C hat etwas mit dem wohl den gleichen Geschmack: Protokolle. Protokolle (Schnittstellen in einigen anderen Sprachen) sind ein Weg, um eine Reihe von Methoden definieren Sie eine Klasse, die nimmt, die Protokolle der Begehung zu implementieren. Ein Protokoll nicht bieten eine Umsetzung aber. Diese Einschränkung verhindert, dass die Verwendung der Protokolle als ein genaues Gegenstück zu Ruby Mixins in Verbindung.
Sogar weniger kurze Antwort: Allerdings die Objective-C runtime hat eine exponierte API, mit dem Sie spielen mit den dynamischen features der Sprache. Dann Sie Schritt außerhalb der Sprache, aber Sie können die Protokolle mit Standard-Implementierungen (auch als konkrete Protokolle). Vladimir ' s Antwort zeigt eine Möglichkeit, das zu tun. An diesem Punkt scheint es mir bekommen Sie Ruby Mixins in Verbindung in Ordnung.
Allerdings bin ich mir nicht sicher, ich würde empfehlen, das zu tun. In den meisten Fällen, sind andere Muster passen die Rechnung, ohne zu spielen Spiele mit der Laufzeit. Zum Beispiel, Sie können ein sub-Objekt, dass die Umsetzung der gemischten Methode (hat-ein statt ist-ein). Spielen mit der Laufzeit ist OK, hat aber 2 Nachteile:
Sie Ihr code weniger lesbar, als es erfordert die Leser wissen viel mehr als die Sprache. Sicher, Sie können (und sollten) in einen Kommentar, aber denken Sie daran, dass alle erforderlichen Kommentar kann angesehen werden als eine Implementierung defekt.
Sind abhängig von , dass Umsetzung der Sprache. Sicher, Apple-Plattformen sind bei weitem die häufigsten für Objective-C, aber vergessen Sie nicht Cocotron oder GnuStep (oder Etoilé), die haben verschiedene Laufzeiten, die möglicherweise oder möglicherweise nicht kompatibel mit Apple auf, dass der Respekt.
Als seitliche Anmerkung, ich Stand unten, dass Kategorien nicht hinzufügen state (Instanz-Variablen) einer Klasse zu. Durch die Nutzung der runtime-API können Sie heben, dass die Beschränkung zu. Dies sprengt den Rahmen dieser Antwort jedoch.
Lange Antwort:
Zwei Objektive-C features wie möglich Kandidaten: Kategorien und Protokolle. Kategorien sind auch nicht wirklich die richtige Wahl hier, wenn ich verstehe die Frage richtig. Die richtige Funktion ist ein Protokoll.
Lassen Sie mich ein Beispiel geben. Angenommen, Sie möchten eine Reihe von Klassen haben eine spezielle Fähigkeit namens "singen". Dann definieren Sie ein Protokoll:
Nun können Sie erklären, dass alle Ihre eigenen Klassen nimmt das Protokoll auf die folgende Weise:
Indem Sie erklären, sich verabschieden das Protokoll verpflichten Sie sich zur Umsetzung der
sing
Methode. Zum Beispiel:Dann werden Sie diese Klassen verwenden, z.B. so:
Beachten Sie, dass der Sänger in dem array nicht brauchen, um haben eine gemeinsame Oberklasse. Beachten Sie auch, dass eine Klasse kann nur eine Superklasse, aber viele Protokolle angenommen. Beachten Sie schließlich, dass die Typprüfung erfolgt durch den compiler.
In Kraft, die Protokoll-Mechanismus ist die mehrfache Vererbung verwendet für die mixin-Muster. Dass Mehrfachvererbung ist stark eingeschränkt, weil ein Protokoll nicht hinzufügen neue Instanz-Variablen einer Klasse. Ein Protokoll beschreibt nur die öffentliche Schnittstelle Anwender implementieren muss. Im Gegensatz zu Ruby-Module, die es nicht enthalten eine Implementierung.
Dass die meisten es. Erwähnen wir noch die Kategorien jedoch.
Kategorie ist für nicht in Spitze Klammern, aber zwischen den Klammern. Der Unterschied ist, dass eine Kategorie definiert werden können, die für eine bestehende Klasse zu erweitern, ohne zu Erben es. Sie können auch so tun, für einen system-Klasse. Wie Sie sich vorstellen können, ist es möglich, Kategorien zu verwenden, um etwas umzusetzen, ähnlich wie Mixins. Und Sie wurden auf diese Weise für eine lange Zeit, in der Regel als Kategorie
NSObject
(die typische Wurzel der Vererbungshierarchie), in einem solchen Ausmaß, dass Sie genannt wurden "informelle" Protokolle.Es ist informell, weil 1 - keine Typ-Prüfung erfolgt durch den compiler und 2 - Umsetzung der Protokoll-Methoden ist optional.
Es gibt keine müssen heute mit Kategorien wie Protokolle, vor allem, weil die formale Protokolle können nun erklären, dass einige Ihrer Methoden sind optional mit dem Schlüsselwort
@optional
oder erforderlich (Standard) mit@required
.Kategorien sind immer noch nützlich, um einige domänenspezifische Verhalten zu einer vorhandenen Klasse.
NSString
ist ein gemeinsames Ziel für das.Es ist auch interessant, darauf hinweisen, dass die meisten (wenn nicht alle)
NSObject
Einrichtungen sind in der Tat erklärten in einerNSObject
Protokoll. Dies bedeutet, dass es nicht wirklich zwingend zu verwendenNSObject
als gemeinsame Oberklasse für alle Klassen, obwohl dies immer noch Häufig geschieht, aus historischen Gründen, und naja... da gibt es keinen Nachteil für Sie dabei. Aber einige system-Klassen, wieNSProxy
sind nichtNSObject
.Car
einesing
Implementierung, diehonks
undRectangle
eine Implementierung, dieflashes
. Mit Ruby Mixins in Verbindung, die Implementierungen sind immer identisch, und stets geteilt. Auch Kategorien können nicht tun, da Sie nicht teilen kann mit anderen Klassen. @Vladimir ' s Antwort ist richtig.Shameless plug: ObjectiveMixin
Es nutzt die Vorteile von Objective-C-Laufzeit-Funktion von hinzufügen von Methoden zu einer Klasse zur Laufzeit (im Gegensatz zu Kategorien, die compile-Zeit nur). Probiert es aus, es funktioniert ziemlich gut und in einer ähnlichen Weise wie Ruby Mixins in Verbindung.
Können Sie buchstäblich mixin den code mit #include. Dies nicht ratsam ist und gegen alle Religionen in objective-c, jedoch funktioniert perfekt.
Bitte, tun Sie es nicht in die Produktion von code.
zum Beispiel in der Datei:
MixinModule.header (sollte nicht kompiliert werden, oder an das Ziel kopiert)
MixinModule.Körper (sollte nicht kompiliert werden, oder an das Ziel kopiert)
in mixin-Klasse:
Anwendungsfall:
Bitte, tun Sie es nicht in die Produktion von code.
Dies ist mein nehmen auf die Umsetzung von Mixins in Verbindung, die in Objective-C, ohne mit der Objective-C runtime direkt. Vielleicht ist es jemandem helfen zu können: https://stackoverflow.com/a/19661059/171933