English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby-Objektorientiert

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.

Ruby-Klassendefinition

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 mitKlassennameend 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).

um Ruby-Objekte zu definieren

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

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

Beispielvariable

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) & 设置器(setter)方法

为了在类的外部读取类中已定义的变量,我们可以通过定义访问器(getter)方法来访问。下面的示例演示了访问器方法的用法:

Online-Beispiel

#!/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 提供了一种在类的外部将参数传入类中已定义的变量,也就是所谓的设置器方法,定义如下:

Online-Beispiel

#!/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 关键字,但它们只能通过类示例来使用,如下面示例所示。它们的功能不限于访问示例变量,也能按照您的需求做更多其他的任务。

Online-Beispiel

#!/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 形式调用,如下面示例所示:

Online-Beispiel

#!/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

to_s-Methode

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:

Online-Beispiel

#!/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)

Zugriffssteuerung

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:

Online-Beispiel

#!/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)

Klassenvererbung

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:

Online-Beispiel

#!/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

Methode überschreiben

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:

Online-Beispiel

#!/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

Operator-Überladung

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

gefrorenen Objekte

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:

Online-Beispiel

#!/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

Klassenkonstante

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.

Online-Beispiel

#!/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.

Verwendung von allocate, um ein Objekt zu erstellen

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:

Online-Beispiel

#!/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

Klasseninformation

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:.

Online-Beispiel

#!/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.