Ruby Objektorientiert
Ruby ist eine rein objektorientierte Sprache, und alles in Ruby hat die Form von Objekten. Jeder Wert in Ruby ist ein Objekt, sogar die primitivsten Dinge: Zeichenketten, Zahlen und sogar true und false sind Objekte. Die Klasse selbst ist auch einObjekt, dieClasseine Instanz der Klasse Class ist. Dieses Kapitel erläutert alle Hauptmerkmale der objektorientierten Programmierung in Ruby.
Klassen werden verwendet, um die Form von Objekten festzulegen. Sie kombinieren Datenrepräsentation und Methoden und organisieren Daten in einem sauberen Paket. Die Daten und Methoden in einer Klasse werden Mitglieder der Klasse genannt.
Ruby-Klassendefinition
Wenn Sie eine Klasse definieren, definieren Sie tatsächlich einen Bauplan für einen Datentyp. Dies definiert eigentlich keine Daten, sondern legt fest, was der Klassenname bedeutet, das heißt, woraus die Objekte der Klasse bestehen und welche Operationen auf dem Objekt ausgeführt werden können.
Eine Klassendefinition beginnt mit dem Schlüsselwortclassund darauf folgtder Klassenname, und endet schließlich mitendein Trennzeichen, um das Ende der Klassendefinition zu markieren. Zum Beispiel verwenden wir das Schlüsselwort class, um die Klasse Box zu definieren, wie unten gezeigt:
Üblicherweise muss der Name mit einem Großbuchstaben beginnen. Wenn er mehrere Wörter enthält, wird der erste Buchstabe jedes Wortes großgeschrieben, jedoch ohne Trennzeichen dazwischen (z. B. CamelCase).
Ruby-Objekte definieren
Klassen liefern den Bauplan für Objekte, daher werden Objekte im Grunde auf Grundlage der Klasse erstellt. Wir verwenden das Schlüsselwortnew, um Objekte der Klasse zu deklarieren. Die folgende Anweisung deklariert zwei Objekte der Klasse Box:
Die initialize-Methode
initializeDie Methode ist eine standardmäßige Ruby-Klassenmethode, dient als Klassenkonstruktor und ähnelt dem Arbeitsprinzip desKonstruktorsin anderen objektorientierten Programmiersprachen. Wenn Sie beim Erstellen eines Objekts einige Klassenvariablen initialisieren möchten, ist die initialize-Methode hilfreich. Diese Methode nimmt eine Reihe von Parametern entgegen; wie bei anderen Ruby-Methoden müssen Sie bei ihrer Verwendung dasdef-Schlüsselwort davor setzen, wie unten gezeigt:
Instanzvariablen
Instanzvariablensind Klassenattribute. Wenn Objekte mit der Klasse erstellt werden, werden sie zu den Attributen der Objekte. Die Attribute jedes Objekts werden separat zugewiesen und teilen keine Werte mit anderen Objekten. Innerhalb der Klasse wird auf diese Attribute mit dem @-Operator zugegriffen; außerhalb der Klasse wird auf sie mit Methoden namensAccessor-Methoden, dievonöffentlichenMethoden sind. Unten nehmen wir die oben definierte KlasseBoxals Beispiel und verwenden @width und @height als Instanzvariablen der Klasse Box.
Accessor-(Getter-) & Setter-(Setter-)Methoden
Um Variablen, die in einer Klasse definiert sind, von außerhalb der Klasse zu lesen, können wir Accessor-(Getter-)Methoden definieren, um auf sie zuzugreifen. Das folgende Beispiel zeigt die Verwendung von Accessor-Methoden:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
盒子宽度 : 10 盒子高度 : 20
Ähnlich wie Accessor-Methoden, die verwendet werden, um auf Variablenwerte zuzugreifen, bietet Ruby eine Möglichkeit, Parameter von außerhalb der Klasse an in einer Klasse definierte Variablen zu übergeben, die sogenanntenSetter-Methoden, die wie folgt definiert sind:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
盒子宽度 : 30 盒子高度 : 50
Da beide Methoden sehr häufig verwendet werden, definiert Rubyattr_accessor :variable_name, attr_reader :variable_name, attr_writer :variable_namedrei Methoden zur Attributdeklaration. Darunter:accessor=reader+writer。
Beachte außerdem: Der Variablenname muss mit:beginnen, und zwischen Variablennamen verwendet man,zur Trennung.
Instanzmethoden
Instanzmethodenwerden genauso wie andere Methoden definiert, und zwar mit demdefSchlüsselwort, aber sie können nur über Klasseninstanzen verwendet werden, wie im folgenden Beispiel gezeigt. Ihre Funktionen sind nicht auf den Zugriff auf Instanzvariablen beschränkt; sie können auch viele andere Aufgaben nach Bedarf ausführen.
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Area of the box is : 200
Klassenmethoden & Klassenvariablen
Klassenvariablensind Variablen, die von allen Instanzen einer Klasse gemeinsam genutzt werden. Mit anderen Worten, auf Klassenvariablen kann von allen Objektinstanzen zugegriffen werden. Klassenvariablen wird ein Präfix aus zwei @-Zeichen (@@) vorangestellt. Klassenvariablen müssen in der Klassendefinition initialisiert werden, wie im folgenden Beispiel gezeigt.
Klassenmethodenwerden mit demdef self.methodname()Schlüsselwort definiert, und Klassenmethoden enden mit dem End-Delimiter. Klassenmethoden können unter Verwendung derclassname.methodname-Form mit dem Klassennamen aufgerufen werden, wie im folgenden Beispiel gezeigt:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Box count is : 2
Die to_s-Methode
Jede Klasse, die Sie definieren, hat eineto_s-Instanzmethode, um die Zeichenfolgendarstellung des Objekts zurückzugeben. Das Folgende ist ein einfaches Beispiel, das Box-Objekte anhand von Breite und Höhe darstellt:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
String representation of box is : (w:10,h:20)
Zugriffskontrolle
Ruby bietet Ihnen drei Stufen des Instanzmethodenschutzes, nämlichpublic, private oder protected. Ruby wendet keine Zugriffskontrolle auf Instanz- und Klassenvariablen an.
- Öffentliche Methoden:Öffentliche Methoden können von jedem Objekt aufgerufen werden. Standardmäßig sind Methoden öffentlich, mit Ausnahme der initialize-Methode, die immer privat ist.
- Private Methoden:Man kann von außerhalb der Klasse nicht auf private Methoden zugreifen oder sie einsehen. Nur Klassenmethoden können auf private Member zugreifen.
- Geschützte Methoden:Geschützte Methoden können nur von Objekten der Klasse und ihrer Unterklassen aufgerufen werden. Der Zugriff kann auch nur innerhalb der Klasse und ihrer Unterklassen erfolgen.
Das Folgende ist ein einfaches Beispiel, das die Syntax dieser drei Modifikatoren demonstriert:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis. Hier ist der erste Methodenaufruf erfolgreich, aber die zweite Methode verursacht ein Problem.
Area of the box is : 200 test.rb:42: protected method `printArea' called for # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
Klassenvererbung
Vererbung ist eines der wichtigsten Konzepte in der objektorientierten Programmierung. Vererbung ermöglicht es uns, eine Klasse auf Basis einer anderen Klasse zu definieren, was das Erstellen und Warten von Anwendungen erleichtert.
Vererbung hilft bei der Wiederverwendung von Code und einer schnellen Ausführung. Leider unterstützt Ruby keine Mehrfachvererbung, aber Ruby unterstütztMixinsMixins. Mixins sind wie eine spezielle Implementierung von Mehrfachvererbung, bei der nur der Schnittstellenteil vererbbar ist.
Wenn eine Klasse erstellt wird, kann der Programmierer direkt angeben, dass die neue Klasse die Mitglieder einer vorhandenen Klasse erbt, wodurch vermieden wird, neue Datenmitglieder und Mitgliedsfunktionen von Grund auf neu zu schreiben. Diese vorhandene Klasse wirdBasisklasse oder Elternklasse genannt, und die neue Klasse wirdabgeleitete Klasse oder Unterklasse genannt。
Ruby bietet auch das Konzept der Unterklassenbildung, was Vererbung ist. Das folgende Beispiel erklärt dieses Konzept. Die Syntax zum Erweitern einer Klasse ist sehr einfach. Fügen Sie einfach ein < Zeichen und den Namen der Elternklasse zur class-Anweisung hinzu. Zum Beispiel definiert das Folgende die KlasseBigBoxJaBoxUnterklasse:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Big box area is : 200
Methodenüberladung
Obwohl du in einer abgeleiteten Klasse neue Funktionalität hinzufügen kannst, möchtest du manchmal das Verhalten einer Methode ändern, die bereits in der Elternklasse definiert ist. In diesem Fall kannst du den Methodennamen unverändert lassen und die Funktionalität der Methode überschreiben, wie im folgenden Beispiel gezeigt:
Beispiel
Ausprobieren »
Die Ausgabe des obigen Beispiels ist:
Big box area is : 200
Operatorüberladung
Wir möchten den +-Operator verwenden, um eine Vektoraddition zweier Box-Objekte durchzuführen, den *-Operator verwenden, um Breite und Höhe von Box zu multiplizieren, und den unären Operator - verwenden, um Breite und Höhe von Box zu negieren. Unten ist eine Version der Box-Klasse mit Definitionen mathematischer Operatoren:
Objekte einfrieren
Manchmal möchten wir verhindern, dass Objekte geändert werden. In Object kann die Methode freeze dies erreichen und ein Objekt effektiv in eine Konstante verwandeln. Jedes Objekt kann eingefroren werden, indem manObject.freezefreeze aufruft. Ein eingefrorenes Objekt kann nicht geändert werden, das heißt, du kannst seine Instanzvariablen nicht ändern.
Du kannst dieObject.frozen?-Methode verwenden, um zu prüfen, ob ein gegebenes Objekt eingefroren wurde. Wenn das Objekt eingefroren ist, gibt diese Methode true zurück; andernfalls gibt sie einen false-Wert zurück. Das folgende Beispiel erläutert dieses Konzept:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
from test.rb:39
Klassenkonstanten
Sie können eine Konstante innerhalb einer Klasse definieren, indem Sie einer Variable einen direkten numerischen oder String-Wert zuweisen. Konstanten müssen nicht @ oder @@ verwenden. Üblicherweise werden Konstantennamen großgeschrieben.
Sobald eine Konstante definiert ist, können Sie ihren Wert nicht ändern. Sie können direkt innerhalb der Klasse auf die Konstante zugreifen, genau wie auf eine Variable, aber wenn Sie von außerhalb der Klasse auf die Konstante zugreifen möchten, müssen Sieclassname::constant:: verwenden, wie im folgenden Beispiel gezeigt.
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Area of the box is : 200 TATA Inc Box weight is: 10
Klassenkonstanten können vererbt werden und können auch wie Instanzmethoden überschrieben werden.
Objekte mit allocate erstellen
Es kann eine Situation geben, in der Sie ein Objekt erstellen möchten, ohne den Objektkonstruktorinitializeaufzurufen, d. h. ohne die Methode new zum Erstellen eines Objekts zu verwenden. In diesem Fall können Sie allocate aufrufen, um ein nicht initialisiertes Objekt zu erstellen, wie im folgenden Beispiel gezeigt:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Area of the box is : 200 test.rb:14: warning: instance variable @width not initialized test.rb:14: warning: instance variable @height not initialized test.rb:14:in `getArea': undefined method `*' for nil:NilClass (NoMethodError) from test.rb:29
Klasseninformation
Rubys self und Javas this haben Ähnlichkeiten, unterscheiden sich aber auch deutlich. In Java werden Methoden innerhalb von Instanzmethoden referenziert, daher verweist this im Allgemeinen auf das aktuelle Objekt. Rubys Code wird Zeile für Zeile ausgeführt, daher hat self in verschiedenen Kontexten unterschiedliche Bedeutungen. Betrachten wir das folgende Beispiel:
Beispiel
Ausprobieren »
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis:
Class of self = Class Name of self = Box
Das bedeutet, dass die Klassendefinition ausgeführt werden kann, indem die Klasse als aktuelles Objekt behandelt wird, und es bedeutet auch, dass die Methoden in der Metaklasse und der Elternklasse während der Ausführung der Methodendefinition verfügbar sind.
Andere Erweiterungen