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

Ruby 面向对象

Ruby è un linguaggio orientato agli oggetti puro, in Ruby tutto si presenta sotto forma di oggetti. Ogni valore in Ruby è un oggetto, anche le cose più primitive: stringhe, numeri, persino true e false sono oggetti. Anche la classe stessa è un对象oggetto è Class

Esempio di classe

La classe viene utilizzata per specificare la forma dell'oggetto, combinando la rappresentazione dei dati e i metodi, organizzando i dati in un pacchetto ben organizzato. I dati e i metodi nella classe sono detti membri della classe.

Definizione della classe Ruby

Quando si definisce una classe, si definisce effettivamente una bozza di tipo di dati. Questo non definisce alcun dato, ma definisce cosa significa il nome della classe, ossia, cosa compone l'oggetto della classe e quali operazioni possono essere eseguite sull'oggetto. class seguito dail nome della classee alla fine con end per separare e terminare la definizione della classe. Ad esempio, usiamo la parola chiave class per definire la classe Box, come mostrato di seguito:

class Box
   code
end

Per convenzione, il nome deve iniziare con una lettera maiuscola, se contiene più parole, ogni parola deve iniziare con una lettera maiuscola, ma non ci sono separatori (ad esempio: CamelCase).

definire l'oggetto Ruby

La classe fornisce un'architettura per gli oggetti, quindi fondamentalmente, gli oggetti vengono creati in base alla classe. Usiamo new La parola chiave dichiara l'oggetto della classe. Le seguenti istruzioni dichiarano due oggetti della classe Box:

box1 = Box.new
box2 = Box.new

metodo initialize

initialize Il metodo è un metodo standard della classe Ruby, che è il costruttore della classe, e corrisponde al metodo initialize degli altri linguaggi di programmazione orientati agli oggetti. costruttore Il metodo initialize è utile quando si desidera inizializzare alcune variabili di classe contemporaneamente alla creazione dell'oggetto. Questo metodo accetta una serie di parametri e, come altri metodi Ruby, deve essere preceduto da def Chiave, come mostrato di seguito:

class Box
   def initialize(w, h)
      @width, @height = w, h
   end
end

variabili di esempio

variabili di esempioSono attributi di classe, che diventano attributi dell'oggetto quando si crea un oggetto della classe. Ogni attributo dell'oggetto è assegnato separatamente e non condivide valori con altri oggetti. All'interno della classe, questi attributi sono acceduti utilizzando l'operatore @, mentre all'esterno della classe, si usa il nome del metodometodi accedentidelPubblicoIl metodo accede. Di seguito, usiamo la classe definita sopra Box Per esempio, usiamo @width e @height come variabili di esempio della classe Box.

class Box
   def initialize(w, h)
      # Assegnazione di valore alla variabile di esempio
      @width, @height = w, h
   end
end

Metodi accedenti (getter) & setter

Per leggere le variabili definite all'interno di una classe dall'esterno della classe, possiamo definire metodi accedenti (getter) per accedervi. Ecco un esempio di come si usa un metodo accedente:

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Costruttore
   def initialize(w, h)
      @width, @height = w, h
   end
 
   # Metodi di accesso
   def printWidth
      @width
   end
 
   def printHeight
      @height
   end
end
 
# Creare un oggetto, inizializzare l'altezza e la larghezza della scatola
box = Box.new(10, 20)
 
# Utilizzo dei metodi di accesso
x = box.printWidth()
y = box.printHeight()
 
puts "Larghezza della scatola : #{x}"
puts "Altezza della scatola : #{y}"

当上面的代码执行时,它会产生以下结果:

Larghezza della scatola : 10
Altezza della scatola : 20

Simile ai metodi di accesso per variabili di valore, Ruby fornisce un modo per passare parametri all'interno della classe già definita, noto comeMetodo di setter,definito come segue:

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
 
   # Metodi di accesso
   def getWidth
      @width
   end
   def getHeight
      @height
   end
 
   # Metodi di immissione
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Utilizzo del metodo di setter
box.setWidth = 30
box.setHeight = 50
 
# Utilizzo dei metodi di accesso
x = box.getWidth()
y = box.getHeight()
 
puts "Larghezza della scatola : #{x}"
puts "Altezza della scatola : #{y}"

当上面的代码执行时,它会产生以下结果:

Larghezza della scatola : 30
Altezza della scatola : 50

Poiché entrambi i metodi sono molto comuni, Ruby ha definito attr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_name Tre metodi di dichiarazione delle proprietà. Tra cui:accessor=reader+writer.

E attenzione: il nome della variabile deve essere preceduto da :, e i nomi delle variabili devono essere separati da ,.

Metodi di esempio

Metodi di esempioLa definizione è uguale a quella degli altri metodi, utilizza def Chiave, ma possono essere utilizzati solo attraverso l'esempio della classe, come nell'esempio seguente. Le loro funzioni non si limitano all'accesso alle variabili dell'esempio, ma possono fare altro secondo la tua esigenza.

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Costruttore
   def initialize(w, h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Call example method
a = box.getArea()
puts "The area of the box is: #{a}"

当上面的代码执行时,它会产生以下结果:

The area of the box is: 200

Metodi di classe & Variabili di classe

Variabile di classeSono variabili condivise tra tutti gli esempi della classe. In altre parole, i valori delle variabili di classe possono essere acceduti da tutti gli oggetti. Le variabili di classe sono prefissate con due caratteri @ (@@), e devono essere inizializzate nella definizione della classe, come nell'esempio seguente.

Metodi di classeUsa def self.methodname() Definita, le classi possono essere definite con il separatore end. I metodi di classe possono utilizzare il nome della classe come prefisso classname.methodname Chiamata formale, come nel seguente esempio:

在线示例

#!/usr/bin/ruby -w
 
class Box
   # Inizializzazione della variabile di classe
   @@count = 0
   def initialize(w, h)
      # Assegnazione di valore alla variabile di esempio
      @width, @height = w, h
 
      @@count += 1
   end
 
   def self.printCount()
      puts "Box count is : #@@count"
   end
end
 
# Creazione di due oggetti
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)
 
# Chiamata al metodo di classe per output del conteggio delle scatole
Box.printCount()

当上面的代码执行时,它会产生以下结果:

Box count is : 2

metodo to_s

Ogni classe che definisci ha to_s Esempio di metodo per restituire la rappresentazione stringa dell'oggetto. Di seguito è riportato un esempio semplice, basato su width e height per l'oggetto Box:

在线示例

#!/usr/bin/ruby -w
 
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
   # Definizione del metodo to_s
   def to_s
      "(w:#@width,h:#@height)" # Oggetto in formato stringa
   end
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Chiamata automatica del metodo to_s
puts "La rappresentazione in stringa della scatola è: #{box}"

当上面的代码执行时,它会产生以下结果:

La rappresentazione in stringa della scatola è: (w:10,h:20)

Controllo dell'accesso

Ruby fornisce tre livelli di protezione dei metodi di esempio, rispettivamente public, private o protectedRuby non applica alcun controllo di accesso ai variabili di esempio e alle variabili di classe.

  • Metodi pubblici: I metodi pubblici possono essere chiamati da qualsiasi oggetto. Di default, i metodi sono pubblici, eccetto il metodo initialize che è sempre privato.

  • Metodi privati: I metodi privati non possono essere acceduti o visti dall'esterno della classe. Solo i metodi della classe possono accedere ai membri privati.

  • Metodi protetti: I metodi protetti possono essere chiamati solo dagli oggetti della classe e dei suoi sottoclassi. L'accesso è consentito solo all'interno della classe e dei suoi sottoclassi.

Di seguito è riportato un esempio semplice che dimostra la sintassi di questi tre modificatori:

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
 
   # I metodi di esempio sono di default pubblici
   def getArea
      getWidth() * getHeight
   end
 
   # Definire i metodi di accesso privati
   def getWidth
      @width
   end
   def getHeight
      @height
   end
   # Renderli privati
   private :getWidth, :getHeight
 
   # Metodo di esempio per output dell'area
   def printArea
      @area = getWidth() * getHeight
      puts "L'area del grande box è: #@area"
   end
   # Il metodo di esempio è protetto
   protected :printArea
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Call example method
a = box.getArea()
puts "The area of the box is: #{a}"
 
# Esempio di chiamata di metodo protetto
box.printArea()

Quando il codice sopra viene eseguito, produce i seguenti risultati. In questo caso, la prima chiamata di metodo è stata eseguita con successo, ma la seconda ha causato un problema.

The area of the box is: 200
test.rb:42: metodo protetto `printArea' chiamato per #
<Box:0xb7f11280 @height=20, @width=10> (NoMethodError)

Ereditarietà della classe

L'ereditarietà è una delle concetti più importanti dell'ingegneria del software orientata agli oggetti. L'ereditarietà ci permette di definire una classe basandoci su un'altra classe, rendendo più facile creare e mantenere le applicazioni.

L'ereditarietà aiuta a riutilizzare il codice e a eseguire rapidamente, sfortunatamente, Ruby non supporta l'ereditarietà multipla, ma Ruby supporta mixinsIl mixin è una specifica implementazione di ereditarietà multipla, dove solo la parte dell'interfaccia è ereditabile.

Quando si crea una classe, il programmatore può specificare direttamente che la nuova classe erediterà i membri di una classe esistente, evitando di scrivere nuovamente i nuovi membri di dati e le funzioni membro. Questa classe esistente viene chiamataClasse madre o classe padre, la nuova classe viene chiamataSottoclasse o sottoclasse.

Ruby fornisce anche il concetto di subclassing, che è l'ereditarietà. Di seguito è spiegato questo concetto. L'uso della sintassi per estendere una classe è molto semplice. Basta aggiungere un < e il nome della classe padre alla dichiarazione della classe. Ad esempio, la seguente definisce la classe BigBox è Box La sottoclasse di

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Definizione della sottoclasse
class BigBox < Box
 
   # Aggiunta di un nuovo metodo di esempio
   def printArea
      @area = @width * @height
      puts "L'area del grande box è: #@area"
   end
end
 
# Creare oggetto
box = BigBox.new(10, 20)
 
# Output dell'area
box.printArea()

当上面的代码执行时,它会产生以下结果:

L'area del grande box è: 200

Sovraccarico dei metodi

Anche se è possibile aggiungere nuove funzionalità nella sottoclasse, a volte potrebbe essere necessario modificare il comportamento di un metodo già definito nella classe padre. In questo caso, è possibile mantenere il nome del metodo invariato e sovraccaricare la funzionalità del metodo, come mostrato nell'esempio seguente:

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Definizione della sottoclasse
class BigBox < Box
 
   # Modifica del metodo esistente getArea
   def getArea
      @area = @width * @height
      puts "L'area del grande box è: #@area"
   end
end
 
# Creare oggetto
box = BigBox.new(10, 20)
 
# Output dell'area utilizzando il metodo sovraccaricato
box.getArea()

Di seguito è riportato l'esempio di output del run:

L'area del grande box è: 200

Sovraccarico degli operatori

Desideriamo utilizzare l'operatore + per eseguire l'addizione vettoriale tra due oggetti Box, utilizzare l'operatore * per moltiplicare width e height di Box, e utilizzare l'operatore unario - per ottenere l'opposto di width e height di Box. Di seguito è riportata una versione della classe Box con definizioni dei simboli matematici:

class Box
  def initialize(w, h) # Inizializza width e height
    @width, @height = w, h
  end
 
  def +(other) # Definisce + per eseguire l'addizione vettoriale
    Box.new(@width + other.width, @height + other.height)
  end
 
  def -@ # Definisce l'operatore unario - per ottenere l'opposto di width e height
    Box.new(-@width, -@height)
  end
 
  def *(scalar) # Esegue la moltiplicazione scalare
    Box.new(@width * scalar, @height * scalar)
  end
end

O oggetto congelato

A volte, vogliamo prevenire che un oggetto venga modificato. In Object, il metodo freeze può fare questo, trasformando efficacemente un oggetto in una costante. Qualsiasi oggetto può essere congelato chiamando Object.freeze per congelare. Gli oggetti congelati non possono essere modificati, ovvero non è possibile modificare le variabili di esempio.

Puoi utilizzare Object.frozen? Il metodo verifica se un oggetto dato è già stato congelato. Se l'oggetto è già stato congelato, il metodo restituisce true, altrimenti restituisce un valore false. Esempio seguente spiega questo concetto:

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
 
   # Metodi di accesso
   def getWidth
      @width
   end
   def getHeight
      @height
   end
 
   # Metodi di immissione
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Congeliamo l'oggetto
box.freeze
if( box.frozen? )
   puts "L'oggetto Box è un oggetto congelato"
else
   puts "L'oggetto Box è un oggetto normale"
end
 
# Ora proviamo a utilizzare i metodi di immissione
box.setWidth = 30
box.setHeight = 50
 
# Utilizzo dei metodi di accesso
x = box.getWidth()
y = box.getHeight()
 
puts "Larghezza della scatola è: #{x}"
puts "Altezza della scatola è: #{y}"

当上面的代码执行时,它会产生以下结果:

L'oggetto Box è un oggetto congelato
test.rb:20:in `setWidth=': non è possibile modificare un oggetto congelato (TypeError)
        from test.rb:39

Costanti di classe

Puoi definire una costante all'interno della classe, assegnando un valore numerico o una stringa a una variabile. La definizione di una costante non richiede l'uso di @ o @@. Per convenzione, i nomi delle costanti sono in maiuscolo.

Una volta definita una costante, non è possibile modificarne il valore. Puoi accedere direttamente alla costante all'interno della classe, come se fosse una variabile, ma se vuoi accedere alla costante dall'esterno della classe, devi utilizzare classname::constantcome indicato nell'esempio seguente.

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   BOX_COMPANY = "TATA Inc"
   BOXWEIGHT = 10
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Creare oggetto
box = Box.new(10, 20)
 
# Call example method
a = box.getArea()
puts "The area of the box is: #{a}"
puts Box::BOX_COMPANY
puts "Box weight is: #{Box::BOXWEIGHT}"

当上面的代码执行时,它会产生以下结果:

The area of the box is: 200
TATA Inc
Box weight is: 10

Class constants can be inherited and can also be overloaded like example methods.

Create an object using allocate

There may be a situation where you want to create an object without calling the object constructor initialize In this case, create an object, that is, create an object using the new method. In this case, you can call allocate to create an uninitialized object, as shown in the following example:.

在线示例

#!/usr/bin/ruby -w
 
# Define class
class Box
   attr_accessor :width, :height
 
   # Constructor method
   def initialize(w, h)
      @width, @height = w, h
   end
 
   # Example method
   def getArea
      @width * @height
   end
end
 
# Create an object using new
box1 = Box.new(10, 20)
 
# Create another object using allocate
box2 = Box.allocate
 
# Example method call using box1
a = box1.getArea()
puts "The area of the box is: #{a}"
 
# Example method call using box2
a = box2.getArea()
puts "The area of the box is: #{a}"

当上面的代码执行时,它会产生以下结果:

The 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

Class information

Ruby's self and Java's this have similarities, but they are also very different. Java methods are always referenced in example methods, so this usually points to the current object. Ruby code is executed line by line, so self has different meanings in different contexts. Let's take a look at the following example:.

在线示例

#!/usr/bin/ruby -w
 
class Box
   # 输出类信息
   puts "self 的类 = #{self.class}"
   puts "self 的名称 = #{self.name}"
end

当上面的代码执行时,它会产生以下结果:

self 的类 = Class
self 的名称 = Box

这意味着类定义可以通过将当前对象作为该类来执行,这也意味着在方法定义执行期间,元类和父类中的该方法都是可用的。