Willkommen zu Teil zwei dieser Einführungsreihe zu Objective-C. Nachdem wir letzte Woche die Grundlagen der C-Sprache, auf der Objective-C aufbaut, besprochen haben, werden wir uns in dieser Woche auf das konzentrieren, was Objective-C zu einer hervorragenden Sprache für die Softwareentwicklung macht. Insbesondere werden wir die Grundlagen der objektorientierten Programmierung (Object Oriented Programming, OOP) diskutieren und zeigen, wie eine Klasse erstellt und Nachrichten an Objekte in Objective-C gesendet werden.
Warum haben wir Objective-C? Warum nicht einfach die zugrunde liegende C-Sprache verwenden? Der Grund, warum wir Objective-C haben, besteht darin, uns einen objektorientierten Spielplatz zur Verfügung zu stellen, auf dem wir unsere Anwendungen erstellen können. OOP ist ein Programmierparadigma, das es Entwicklern ermöglicht, über das Softwaredesign in Form von Objekten und Attributen statt von Variablen und Funktionen nachzudenken. Insbesondere versucht OOP, Datenabstraktion, Einkapselung, Modularität, Polymorphie und Vererbung zu erhalten. Das Thema OOP kann leicht ein Buch (oder eine Tutorialserie) selbst füllen, daher werde ich Ihnen stattdessen die Grundprinzipien als Beispiel vorstellen.
Stellen Sie sich vor, Sie haben ein Auto. Sie können sich Ihr Auto als Objekt vorstellen. Es gibt viele andere Autos auf der Welt und Sie könnten sogar mehr als eines besitzen. Ihr Auto hat verschiedene Eigenschaften: Marke, Modell, Farbe, Motortyp und viele mehr. In der objektorientierten Programmierung bezeichnen wir das abstrakte Konzept eines Autos als „Klasse“ und das einzelne Auto, dem Sie ein Objekt oder eine Instanz (instanziiertes Objekt) der Klasse gehören. Wenn ein neues Auto hergestellt wird, wird eine neue Instanz der Fahrzeugklasse instanziiert (oder erstellt) und mit eigenen Eigenschaften versehen.
Noch ein wenig unscharf? Eine weitere großartige Analogie ist die des Plätzchens und des Ausstechers. Die Klasse ist der Ausstecher und das Objekt ist der Cookie.
Warum also in Objekten denken? Einer der besten Gründe liegt darin, dass Ihr Gehirn das Leben in der realen Welt auf natürliche Weise konzeptualisiert und es viele Vorteile bringt, Softwareentwicklung in ähnlicher Weise abstrahieren zu können.
Klassen (und damit Objekte) setzen sich aus Methoden und Attributen zusammen. Wenn Sie aus einer anderen Programmiersprache stammen, sind Sie vielleicht eher damit vertraut, Methoden mit Funktionen und Attributen mit Variablen gleichzusetzen. Als nächstes werden wir uns nacheinander besprechen.
Wir haben also eine "Instanz" eines Autos, was machen wir jetzt damit? Wir fahren es und füllen es unter anderem mit Benzin. Fahren und Tanken mit Benzin gilt nur für die Autos, die wir verwenden, dh wenn wir ein Auto tanken oder ein Auto fahren, wirken wir nur auf eine Instanz und nicht auf alle Autos der Welt. Daher wird das Auffüllen der Autoinstanz als ein Instanzmethode. Es ist etwas, was wir mit unserer Instanz tun und nur mit unserer Instanz.
Auf der anderen Seite, wenn wir die ursprüngliche Fahrzeugklasse fragen, wie viele Fahrzeugfarben verfügbar sind, ist dies eine Klassenmethode, da wir nicht mehr nur über das Auto sprechen, sondern alle Autos im Allgemeinen.
Viele dieser Prinzipien werden mit der Verwendung klarer. Schauen wir uns also ein bisschen Syntax an.
In Objective-C rufen wir Objektmethoden auf, indem wir Nachrichten übergeben. Wenn wir wissen möchten, wie viel Gas in unserer Instanz von Auto vorhanden ist, senden wir eine Nachricht an unsere Instanz und die Nachricht ist die Methode, die wir anwenden möchten. Programmatisch sieht es so aus:
[Empfängernachricht];
Die Klammern zeigen an, dass wir eine Nachricht senden. Der erste Parameter ist, wer diese Nachricht erhalten soll, und der zweite Parameter ist, was die Nachricht eigentlich ist. Schließlich enden wir mit einem Semikolon, wie es in den meisten Programmiersprachen üblich ist.
In Anbetracht unseres vorherigen Beispiels würden wir auf diese Weise mit unserem Beispiel Auto interagieren, um dem Tank Gas zuzuführen.
[dansCar addGas];
Im obigen Beispiel wird davon ausgegangen, dass wir eine Instanz der Car-Klasse instanziiert haben und diese als "dansCar" bezeichnet haben. Dann übergeben wir die Nachricht "addGas" an das Objekt "dansCar", das dem Aufrufen einer Funktion entspricht. In einer anderen Sprache könnte diese Zeile folgendermaßen aussehen:
dansCar.addGas ();
Nehmen wir an, unsere Fahrzeugklasse hat einen prozentual gespeicherten Tank. Wenn der Gastank beispielsweise zu 50% gefüllt ist, ist er halb voll und bei 100% ist er bis zum Rand gefüllt. Wenn wir wissen wollen, wie viel Gas sich im Tank befindet, nehmen wir diese Informationen nicht direkt aus einem Attribut. Stattdessen würden wir eine Zugriffsmethode verwenden, um auf die interne Variable für uns zuzugreifen. Wenn wir den Tank füllen möchten, geben wir dem Gastankerattribut nicht nur einen neuen Prozentsatz an, sondern verwenden einen Setter, um das Attribut für uns zu aktualisieren. Dieser Vorgang wird als Datenkapselung bezeichnet.
Mit der Verkapselung von Daten meinen wir, dass Daten (sozusagen) von Methoden enthalten sind, die für den Zugriff auf die Daten bedeutsam sind. Dazu müssen wir Methoden verwenden. Einige von Ihnen, die in anderen Sprachen programmiert haben und noch nichts von der Datenkapselung gehört haben, fragen sich vielleicht, warum wir so vorgehen. Die Antwort ist, dass durch das Einkapseln von Daten ein schönes Kissen zwischen dem Entwickler einer Klasse und dem Benutzer einer Klasse entsteht. Da die Klassenmethoden die Attribute innerhalb der Klasse verwalten und verwalten, können sie die Datenintegrität leichter bewahren. Ein weiterer großer Vorteil ist, dass wenn ein Entwickler seine Klasse verteilt, die Benutzer, die sie verwenden, sich nicht um die Interna der Klasse kümmern müssen. Ein Entwickler kann eine Methode aktualisieren, um sie schneller oder effizienter zu machen, aber diese Aktualisierung ist für den Benutzer der Klasse transparent, da er / sie immer noch dieselbe Methode verwendet, ohne den Code zu ändern.
Dies bringt uns gut zum nächsten Abschnitt, den wir uns anschauen werden. So trennt Objective-C die Schnittstelle von der Implementierung.
Wenn Sie in Objective-C eine einfache Klasse erstellen oder damit arbeiten, werden Sie feststellen, dass diese standardmäßig über zwei Dateien verfügt. Die Implementierungsdatei ist eine Datei, die mit dem Suffix .m endet, und die Schnittstellendatei, die eine Datei ist, die mit dem Suffix .h endet.
#einführen@interface Car: NSObject // Hier gehen Attribute auf Float fillLevel; // Hier gehen die Methoden hin - (void) addGas; @Ende
Zunächst importieren wir Cocoa.h, eine Standardbibliothek mit viel wiederverwendbarem Code, den wir in unserer App verwenden können.
Als Nächstes erklären wir, dass dies die Schnittstelle für das Auto ist, aber wir fügen auch NSObject in diese Deklaration ein. Das Hinzufügen von:: NSObject bedeutet, dass die Car-Klasse von der NSObject-Klasse erbt. In einem zukünftigen Tutorial werden wir mehr über Vererbung sprechen.
Als Nächstes wird unsere Instanzvariable "fillLevel" deklariert. Wir geben an, dass sie vom Datentyp "float" ist, sodass wir leicht einen Prozentsatz darstellen können.
In der nächsten Zeile wird unsere Methode "addGas" angegeben. Das "-" zeigt an, dass dies eine Instanzmethode ist, keine Klassenmethode. Der Teil "(void)" bedeutet, dass die Methode nach der Ausführung nichts zurückgibt. Wenn die Klasse eine Ganzzahl zurückgeben würde, würde diese in "(int)" und für jeden anderen Datentyp gleich sein. Abschließend schließen wir die Methodendeklaration mit einem Semikolon ab.
#import "Car.h" @implementation Car - (void) addGas // Code wird hier hinzugefügt, um Gas hinzuzufügen @end
Die Implementierung enthält in diesem Fall die Methode, um dem Tank Gas zuzuführen. Wir importieren auch Car.h, die Schnittstellendatei. Wo sich unsere addGas-Methode befindet, können wir noch viele weitere Methoden hinzufügen. Der heutige Anwendungsbereich besteht jedoch darin, Sie einfach zu verstehen, wie Klassen funktionieren, anstatt eine vollwertige Klasse zu erstellen.
Beim nächsten Mal werden Methoden und die Verwendung von Variablen mit Methoden (sowie die Grundlagen zum Verwalten von Variablen in Objective-C) eingehender untersucht. Dieses Tutorial war nicht zu lang, da es für neue Entwickler oft etwas verwirrend ist, warum wir Klassen in mehr als eine Datei aufteilen. Wenn Sie sich verwirrt fühlen, lesen Sie bitte die obigen Informationen erneut oder stellen Sie Fragen in den Kommentaren. Die Klassen werden in dieser Serie ständig wiederkehren und es ist wichtig, dass Sie verstehen, wie sie funktionieren.
Da dieser Teil der Serie ziemlich theoretisch war, können Sie nicht zu viel üben. Ich empfehle Ihnen diese Woche jedoch, sich für die Entwickler-Website von Apple anzumelden, da dies eine unschätzbare Referenz ist. Nachdem Sie das getan haben, können Sie sich einige der herunterladbaren Klassen ansehen und ein paar einfache herunterladen. Sie müssen nicht den gesamten Code verstehen. Schauen Sie sich nur an, wie die Klassen gebildet und zwischen Dateien getrennt werden.