English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Ruby ist eine rein objektorientierte Sprache, in Ruby tritt alles in Form von Objekten auf. Jeder Wert in Ruby ist ein Objekt, selbst die ursprünglichsten Dinge: Strings, Zahlen, und sogar true und false sind Objekte. Die Klasse selbst ist auch einObjekt, ist Klasse Ein Beispiel für eine Klasse. In diesem Kapitel werden alle wichtigen Funktionen der objektorientierten Programmierung in Ruby erläutert.
Die Klasse wird verwendet, um das Erscheinungsbild des Objekts zu spezifizieren, kombiniert Datenrepräsentation und Methoden, um Daten in ein regelmäßiges Paket zu organisieren. Die Daten und Methoden in der Klasse werden als Klassenmitglieder bezeichnet.
Wenn Sie eine Klasse definieren, definieren Sie实际上 eine Datenartenskizze. Dies definiert tatsächlich keine Daten, sondern definiert, was der Klassename bedeutet, d.h., was die Klasse enthält und welche Operationen auf dem Objekt ausgeführt werden können.
Die Klasse definition ist durch das Schlüsselwort class beginnt mitKlassenname。 end zur Trennung und Beendigung der Klasse verwenden. Zum Beispiel verwenden wir den Schlüsselwort class, um die Klasse Box zu definieren, wie folgt:
class Box code end
Laut Konvention muss der Name mit einem Großbuchstaben beginnen, und wenn mehrere Wörter enthalten sind, muss jeder Wortanfang groß geschrieben werden, ohne Trennzeichen (z.B.: CamelCase).
Die Klasse bietet ein Blaupause für Objekte, daher werden Objekte im Allgemeinen nach der Klasse erstellt. Wir verwenden new Schlüsselwort zur Erklärung des Klasse-Objekts. Die folgenden Anweisungen erklären zwei Objekte der Klasse Box:
box1 = Box.new box2 = Box.new
initialize Methode ist eine Standard-Ruby-Klassenmethode und der Konstruktor der Klasse, ähnlich wie der initialize-Methode in anderen objektorientierten Programmiersprachen. Konstruktor Der Mechanismus ist ähnlich. Wenn Sie einige Klassenvariablen gleichzeitig mit der Erstellung eines Objekts initialisieren möchten, ist die initialize-Methode nützlich. Diese Methode hat eine Reihe von Parametern und wie andere Ruby-Methoden auch muss sie vor der Verwendung def Schlüsselwort wie folgt angegeben:
class Box def initialize(w,h) @width, @height = w, h end end
BeispielvariableKlassenattribute, die sich in den Attributen von Objekten ändern, wenn mit der Klasse ein Objekt erstellt wird. Jedes Objekt hat seine eigenen Attributwerte, die nicht mit anderen Objekten geteilt werden. Innerhalb der Klasse werden diese Attribute mit dem @-Operator und außerhalb der Klasse mit dem so genannten访问器方法的公共方法进行访问。下面我们以上面定义的类 Box 为示例,把 @width 和 @height 作为类 Box 的示例变量。
class Box def initialize(w,h) # 给示例变量赋值 @width, @height = w, h end end
为了在类的外部读取类中已定义的变量,我们可以通过定义访问器(getter)方法来访问。下面的示例演示了访问器方法的用法:
#!/usr/bin/ruby -w # Klassendefinition class Box # 构造函数 def initialize(w,h) @width, @height = w, h end # Zugriffsmethoden def printWidth @width end def printHeight @height end end # 创建对象,初始化盒子的高度与宽度 box = Box.new(10, 20) # Verwenden Sie Zugriffsmethoden x = box.printWidth() y = box.printHeight() puts "盒子宽度 : #{x}" puts "盒子高度 : #{y}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
盒子宽度 : 10 盒子高度 : 20
与用于访问变量值的访问器方法类似,Ruby 提供了一种在类的外部将参数传入类中已定义的变量,也就是所谓的设置器方法,定义如下:
#!/usr/bin/ruby -w # Klassendefinition class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Zugriffsmethoden def getWidth @width end def getHeight @height end # Setter-Methoden def setWidth=(value) @width = value end def setHeight=(value) @height = value end end # Erstellung eines Objekts box = Box.new(10, 20) # 使用设置器方法 box.setWidth = 30 box.setHeight = 50 # Verwenden Sie Zugriffsmethoden x = box.getWidth() y = box.getHeight() puts "盒子宽度 : #{x}" puts "盒子高度 : #{y}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
盒子宽度 : 30 盒子高度 : 50
由于两种方法非常常用,Ruby 定义了 attr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_name 三种属性声明方法。其中:accessor=reader+writer.
同时注意:变量名前一定要带 : ,变量名之间要用 , 分割。
示例方法的定义与其他方法的定义一样,都是使用 def 关键字,但它们只能通过类示例来使用,如下面示例所示。它们的功能不限于访问示例变量,也能按照您的需求做更多其他的任务。
#!/usr/bin/ruby -w # Klassendefinition class Box # 构造方法 def initialize(w,h) @width, @height = w, h end # Beispielmethod def getArea @width * @height end end # Erstellung eines Objekts box = Box.new(10, 20) # Aufruf eines Beispielmethods a = box.getArea() puts "Fläche des Kastens ist: #{a}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Fläche des Kastens ist: 200
类变量是在类的所有示例中共享的变量。换句话说,类变量的示例可以被所有的对象示例访问。类变量以两个 @ 字符(@@)作为前缀,类变量必须在类定义中被初始化,如下面示例所示。
类方法使用 def self.methodname() 定义,类方法以 end 分隔符结尾。类方法可使用带有类名称的 classname.methodname 形式调用,如下面示例所示:
#!/usr/bin/ruby -w class Box # 初始化类变量 @@count = 0 def initialize(w,h) # 给示例变量赋值 @width, @height = w, h @@count += 1 end def self.printCount() puts "Box count is: #@@count" end end # Erstellen Sie zwei Objekte box1 = Box.new(10, 20) box2 = Box.new(30, 100) # Rufen Sie die Klasse Methode zum Ausgeben des Kästchenzählers auf Box.printCount()
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Box count ist : 2
Jede von Ihnen definierte Klasse hat eine to_s Beispielmethoden, um die Zeichenfolge der Zeichenkette des Objekts zurückzugeben. Hier ist ein einfaches Beispiel, das das Box-Objekt basierend auf width und height darstellt:
#!/usr/bin/ruby -w class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Definieren Sie die to_s-Methode def to_s "(w:#@width,h:#@height)" # Objektformat end end # Erstellung eines Objekts box = Box.new(10, 20) # Automatischer Aufruf der to_s-Methode puts "String-Darstellung des Kästchens ist: #{box}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
String-Darstellung des Kästchens ist: (w:10,h:20)
Ruby bietet Ihnen drei Ebenen der Beispielmethoden-Schutz, nämlich public, privat oder geschützt. Ruby wendet keine Zugriffssteuerung auf Beispiele und Klassenvariablen an.
Öffentliche Methoden: Öffentliche Methoden können von jedem Objekt aufgerufen werden. Standardmäßig sind Methoden öffentlich, außer dass der Initialisierer immer privat ist.
Private Methoden: Private Methoden können nicht von außerhalb der Klasse aufgerufen oder betrachtet werden. Nur Methoden der Klasse können auf private Mitglieder zugreifen.
Geschützte Methoden: Geschützte Methoden können nur von Objekten der Klasse und deren Subklassen aufgerufen werden. Der Zugriff erfolgt nur innerhalb der Klasse und deren Subklassen.
Hier ist ein einfaches Beispiel, das die Syntax dieser drei Modifikatoren zeigt:
#!/usr/bin/ruby -w # Klassendefinition class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Beispielmethoden sind standardmäßig öffentlich def getArea getWidth() * getHeight end # Definieren Sie private Zugriffsmethoden def getWidth @width end def getHeight @height end # Machen Sie sie privat privat :getWidth, :getHeight # Beispielmethoden zum Ausgeben der Fläche def printArea @area = getWidth() * getHeight puts "Große Boxfläche ist: #@area" end # Machen Sie die Beispielmethoden geschützt geschützt :printArea end # Erstellung eines Objekts box = Box.new(10, 20) # Aufruf eines Beispielmethods a = box.getArea() puts "Fläche des Kastens ist: #{a}" # Versuch, einen geschützten Beispielmethoden aufzurufen box.printArea()
Wenn der obige Code ausgeführt wird, ergibt er das folgende Ergebnis. Hierbei wurde der erste Aufruf erfolgreich, aber der zweite Aufruf verursacht ein Problem.
Fläche des Kastens ist: 200 test.rb:42: geschützte Methode `printArea' auf # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
Vererbung, ist eines der wichtigsten Konzepte der objektorientierten Programmierung. Vererbung ermöglicht es uns, eine Klasse auf Basis einer anderen Klasse zu definieren, was die Erstellung und Wartung von Anwendungen einfacher macht.
Vererbung hilft bei der Wiederverwendung von Code und beschleunigt die Ausführung, leider unterstützt Ruby keine Mehrvererbung, aber Ruby unterstützt Mixins.Mixin ist eine spezifische Implementierung von Mehrvererbung, bei der nur der Interface-Teil vererbt wird.
Wenn eine Klasse erstellt wird, kann der Programmierer direkt angeben, dass die neue Klasse die Mitglieder einer vorhandenen Klasse übernimmt, ohne neue Datenmitglieder und -funktionen neu zu schreiben. Diese vorhandene Klasse wirdBasisklasse oder OberklassewirdAbleitungsklasse oder Unterklasse.
Ruby bietet auch das Konzept der Subklasse, das Subklassifizieren ist, wie das Erklärung des Konzepts gezeigt. Die Syntax zur Erweiterung einer Klasse ist sehr einfach. Es reicht aus, ein <-Zeichen und den Namen der Oberklasse zur Klassenerklärung hinzuzufügen. Zum Beispiel definiert der folgende Code die Klasse BigBox ist Box der Unterklasse:
#!/usr/bin/ruby -w # Klassendefinition class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Beispielmethod def getArea @width * @height end end # Definition der Unterklasse class BigBox < Box # Neue Beispielmethode hinzufügen def printArea @area = @width * @height puts "Große Boxfläche ist: #@area" end end # Erstellung eines Objekts box = BigBox.new(10, 20) # Fläche ausgeben box.printArea()
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Große Boxfläche ist: 200
Obwohl Sie neue Funktionen in der Ableitungsklasse hinzufügen können, möchten Sie manchmal das Verhalten von Methoden, die bereits in der Oberklasse definiert sind, ändern. In diesem Fall können Sie den Methodennamen beibehalten und die Funktion der Methode überschreiben, wie im folgenden Beispiel gezeigt:
#!/usr/bin/ruby -w # Klassendefinition class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Beispielmethod def getArea @width * @height end end # Definition der Unterklasse class BigBox < Box # Änderung der bestehenden getArea-Methode def getArea @area = @width * @height puts "Große Boxfläche ist: #@area" end end # Erstellung eines Objekts box = BigBox.new(10, 20) # Mit der überschriebenen Methode die Fläche ausgeben box.getArea()
Die folgenden Beispiele geben das Ausgaberesultat an:
Große Boxfläche ist: 200
Wir möchten verwenden + Operator um die Vektoraddition von zwei Box-Objekten durchzuführen, verwendet * Operator um die width und height des Box zu multiplizieren, verwendet einen einzeiligen Operator - Umgekehrte width und height des Box berechnen. Hier ist eine Version der Box-Klasse mit definierten mathematischen Operatoren:
class Box def initialize(w,h) # Initialisierung von width und height @width, @height = w, h end def +(other) # Definition + um die Vektoraddition durchzuführen Box.new(@width + other.width, @height + other.height) end def -# Definition eines einzeiligen Operators - umgekehrte width und height berechnen Box.new(-@width, -@height) end def *(skalar) # Ausführung der Skalarvermultiplikation Box.new(@width*skalar, @height*skalar) end end
Manchmal möchten wir verhindern, dass ein Objekt geändert wird. In Object kann die Methode freeze dies erreichen und ein Objekt effektiv in eine Konstante umwandeln. Jedes Objekt kann durch Aufruf Object.freeze verwenden, um zu frieren. Gefrorene Objekte können nicht geändert werden, das bedeutet, Sie können keine Beispielvariablen ändern.
Sie können Object.frozen? Die Methode überprüft, ob ein gegebenes Objekt bereits gefroren ist. Wenn das Objekt bereits gefroren ist, gibt die Methode true zurück, andernfalls gibt sie einen falschen Wert zurück. Das folgende Beispiel erläutert dieses Konzept:
#!/usr/bin/ruby -w # Klassendefinition class Box # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Zugriffsmethoden def getWidth @width end def getHeight @height end # Setter-Methoden def setWidth=(value) @width = value end def setHeight=(value) @height = value end end # Erstellung eines Objekts box = Box.new(10, 20) # Lassen Sie das Objekt einfrieren box.freeze if(box.frozen?) puts "Box-Objekt ist ein gefrorenes Objekt" else puts "Box-Objekt ist normales Objekt" end # Versuchen Sie, Setter-Methoden zu verwenden box.setWidth = 30 box.setHeight = 50 # Verwenden Sie Zugriffsmethoden x = box.getWidth() y = box.getHeight() puts "Breite des Kastens ist: #{x}" puts "Höhe des Kastens ist: #{y}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Box-Objekt ist ein gefrorenes Objekt test.rb:20:in `setWidth=': kann nicht auf ein gefrorenes Objekt zugegriffen werden (TypeError) von test.rb:39
Sie können eine Konstante in der Klasse definieren, indem Sie einen direkten numerischen oder zeichenbasierten Wert einer Variable zuweisen. Die Definition einer Konstante erfordert keine Verwendung von @ oder @@. Nach Konvention werden die Namen von Konstanten in Großbuchstaben geschrieben.
Sobald eine Konstante definiert wurde, können Sie ihren Wert nicht ändern. Sie können Konstanten in der Klasse direkt wie Variablen aufrufen, aber wenn Sie die Konstante außerhalb der Klasse aufrufen möchten, müssen Sie classname::constantwie im folgenden Beispiel gezeigt.
#!/usr/bin/ruby -w # Klassendefinition class Box BOX_COMPANY = "TATA Inc" BOXWEIGHT = 10 # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Beispielmethod def getArea @width * @height end end # Erstellung eines Objekts box = Box.new(10, 20) # Aufruf eines Beispielmethods a = box.getArea() puts "Fläche des Kastens ist: #{a}" puts Box::BOX_COMPANY puts "Box Gewicht ist: #{Box::BOXWEIGHT}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Fläche des Kastens ist: 200 TATA Inc Box Gewicht ist: 10
Klassenkonstanten können vererbt werden und wie Beispielmethoden auch überschrieben werden.
Es kann eine Situation geben, in der Sie den Objektconstructor nicht aufrufen möchten initialize In diesem Fall wird ein Objekt erstellt, d.h. ein Objekt wird mit dem new-Methoden erstellt. In diesem Fall können Sie allocate aufrufen, um ein nicht initialisiertes Objekt zu erstellen, wie im folgenden Beispiel gezeigt:
#!/usr/bin/ruby -w # Klassendefinition class Box attr_accessor :width, :height # Konstruktormethode def initialize(w,h) @width, @height = w, h end # Beispielmethod def getArea @width * @height end end # Verwendung von new, um ein Objekt zu erstellen box1 = Box.new(10, 20) # Verwendung von allocate, um ein weiteres Objekt zu erstellen box2 = Box.allocate # Verwendung von box1 Aufruf eines Beispielmethods a = box1.getArea() puts "Fläche des Kastens ist: #{a}" # Verwendung von box2 Aufruf eines Beispielmethods a = box2.getArea() puts "Fläche des Kastens ist: #{a}"
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Fläche des Kastens ist: 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
Ruby hat mit self ähnliche, aber auch sehr unterschiedliche Eigenschaften im Vergleich zu Java. Java-Methode werden immer im Beispielmodus verwendet, daher verweist this normalerweise auf das aktuelle Objekt. In Ruby wird der Code Zeile für Zeile ausgeführt, daher hat self in verschiedenen Kontexten (context) verschiedene Bedeutungen. Lassen Sie uns einen Beispielcode betrachten:.
#!/usr/bin/ruby -w class Box # Ausgabe der Klasseinformationen puts "Klasse von self = #{self.class}" puts "Name von self = #{self.name}" end
Wenn der obige Code ausgeführt wird, wird das folgende Ergebnis erzeugt:
Klasse von self = Class Name von self = Box
Das bedeutet, dass die Klasse definiert wird, indem die Klasse als aktueller Objekt ausgeführt wird, und es bedeutet auch, dass die Methode in der Metaklasse und im Elternteilklassen während der Ausführung der Methodedefinition verfügbar ist.