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

Programación orientada a objetos en Ruby

Ruby es un lenguaje orientado a objetos puro, donde todo se presenta en forma de objeto. Cada valor en Ruby es un objeto, incluso lo más primitivo: cadenas de caracteres, números, e incluso true y false son objetos. La clase en sí también es unobjetoes Class Ejemplo de clase

La clase se utiliza para especificar la forma del objeto, combinando la representación de datos y los métodos, organizando los datos en un paquete ordenado. Los datos y métodos dentro de la clase se denominan miembros de la clase.

Definición de clase Ruby

Al definir una clase, realmente define un plano de tipo de datos. Esto no define ningún dato en sí, sino que define lo que significa el nombre de la clase, es decir, define qué compone el objeto de la clase y qué operaciones se pueden realizar en el objeto.

La definición de la clase se realiza con la palabra clave class Seguido deNombre de la clase,finalizando con un final Para separar y finalizar la definición de la clase. Por ejemplo, usamos la palabra clave class para definir la clase Box, como se muestra a continuación:

class Box
   code
final

Por convención, el nombre debe comenzar con una letra mayúscula, y si contiene múltiples palabras, cada palabra debe comenzar con mayúscula, sin separadores entre ellas (por ejemplo: CamelCase).

Para definir un objeto Ruby

La clase proporciona el plano de los objetos, por lo que básicamente, los objetos se crean según la clase. Usamos new La palabra clave se utiliza para declarar el objeto de la clase. Las siguientes declaraciones declaran dos objetos de la clase Box:

box1 = Box.new
box2 = Box.new

initialize

initialize El método es un método de clase estándar de Ruby, que es el constructor de la clase, similar al método initialize en otros lenguajes de programación orientados a objetos. Constructor El principio de funcionamiento es similar. Cuando desea inicializar algunas variables de clase al crear un objeto, el método initialize es muy útil. Este método tiene una serie de parámetros, al igual que otros métodos de Ruby, y se debe colocar def Palabra clave, como se muestra a continuación:

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

Variable de ejemplo

Variable de ejemploSon propiedades de clase, que se convierten en propiedades del objeto al crear un objeto de la clase. Cada propiedad del objeto se asigna de manera separada, sin compartir valores entre otros objetos. Dentro de la clase, se accede a estas propiedades utilizando el operador @, y desde fuera de la clase, se utiliza lo que se conoce comométodos de accesodelPúblicométodo para acceder. A continuación, utilizamos la clase definida anteriormente Box Por ejemplo, @width y @height como variables de instancia de la clase Box.

class Box
   def initialize(w,h)
      # Asignación de ejemplo a la variable
      @width, @height = w, h
   final
final

Métodos de acceso (getter) & Métodos de configuración (setter)

Para leer las variables definidas en la clase desde el exterior, podemos definir métodos de acceso (getter) para acceder. A continuación, se muestra el uso de los métodos de acceso (getter):

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor
   def initialize(w,h)
      @width, @height = w, h
   final
 
   # Métodos de acceso
   def printWidth
      @width
   final
 
   def printHeight
      @height
   final
final
 
# Creación de objetos, inicialización de la altura y anchura de la caja
box = Box.new(10, 20)
 
# Uso de métodos de acceso
x = box.printWidth()
y = box.printHeight()
 
puts "Anchura de la caja: #{x}"
puts "Altura de la caja: #{y}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Anchura de la caja: 10
Altura de la caja: 20

Son similares a los métodos de acceso (accessor) utilizados para acceder a los valores de las variables, Ruby proporciona una manera de pasar parámetros a las variables ya definidas en la clase desde el exterior, lo que se conoce comoMétodos de configuración,definido como follows:

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
 
   # Métodos de acceso
   def getWidth
      @width
   final
   def getHeight
      @height
   final
 
   # Métodos de configuración
   def setWidth=(value)
      @width = value
   final
   def setHeight=(value)
      @height = value
   final
final
 
# Create object
box = Box.new(10, 20)
 
# Uso del método de configuración
box.setWidth = 30
box.setHeight = 50
 
# Uso de métodos de acceso
x = box.getWidth()
y = box.getHeight()
 
puts "Anchura de la caja: #{x}"
puts "Altura de la caja: #{y}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Anchura de la caja: 30
Altura de la caja: 50

Dado que ambos métodos son muy comunes, Ruby ha definido attr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_name tres métodos de declaración de atributos. De los cuales:accessor=reader+writer.

Además, asegúrese de que el nombre de la variable esté precedido por : y los nombres de las variables estén separados por ,

métodos de instancia

métodos de instanciadefinición es similar a la de otros métodos, también se utiliza def Palabras clave, pero solo se pueden usar a través de instancias de clase, como se muestra en el siguiente ejemplo. Su funcionalidad no se limita a acceder a las variables de instancia, también pueden realizar otras tareas según sus necesidades.

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor
   def initialize(w,h)
      @width, @height = w, h
   final
   # Example method
   def getArea
      @width * @height
   final
final
 
# Create object
box = Box.new(10, 20)
 
# Call example method
a = box.getArea()
puts "Area of the box is: #{a}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Area of the box is: 200

Métodos de clase & Variables de clase

Variable de claseson variables compartidas entre todas las instancias de la clase. En otras palabras, las instancias de la variable de clase pueden ser accedidas por todas las instancias de los objetos. Las variables de clase se prefijan con dos caracteres @ (@@), y las variables de clase deben inicializarse dentro de la definición de la clase, como se muestra en el siguiente ejemplo.

métodos de claseUso def self.methodname() Definición, los métodos de clase terminan con el separador end. Los métodos de clase pueden usar classname.methodname Llamada de forma, como se muestra en el siguiente ejemplo:

Ejemplos en línea

#!/usr/bin/ruby -w
 
class Box
   # Inicialización de la variable de clase
   @@count = 0
   def initialize(w,h)
      # Asignación de ejemplo a la variable
      @width, @height = w, h
 
      @@count += 1
   final
 
   def self.printCount()
      puts "Cuenta de caja: #@@count"
   final
final
 
# Crear dos objetos
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)
 
# Llamar al método de clase para salida del recuento de cajas
Box.printCount()

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Box count es: 2

método to_s

Cualquier clase que defina tiene un to_s Los métodos de ejemplo devuelven la representación de cadena del objeto. A continuación, se muestra un ejemplo simple que representa el objeto Box según el ancho y la altura:

Ejemplos en línea

#!/usr/bin/ruby -w
 
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
   # Definir el método to_s
   def to_s
      "(w:#@width,h:#@height)"  # Formato de cadena del objeto
   final
final
 
# Create object
box = Box.new(10, 20)
 
# Llamar automáticamente al método to_s
puts "Representación de cadena de la caja es: #{box}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Representación de cadena de la caja es: (w:10,h:20)

Control de acceso

Ruby ofrece tres niveles de protección de métodos de ejemplo,分别是 public、private o protected.Ruby no aplica ningún control de acceso a las variables de ejemplo y de clase.

  • Métodos públicos: Los métodos públicos pueden ser llamados por cualquier objeto. Por defecto, todos los métodos son públicos, excepto el método initialize, que siempre es privado.

  • Métodos privados: Los métodos privados no pueden ser accedidos ni vistos desde el exterior de la clase. Solo los métodos de la clase pueden acceder a los miembros privados.

  • Métodos protegidos: Los métodos protegidos solo pueden ser llamados por objetos de la clase y sus subclases. El acceso también se puede realizar solo dentro de la clase y sus subclases.

A continuación, se muestra un ejemplo simple que ilustra la sintaxis de estos tres modificador

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
 
   # Los métodos de ejemplo son públicos por defecto
   def getArea
      getWidth() * getHeight
   final
 
   # Definir métodos de acceso privados
   def getWidth
      @width
   final
   def getHeight
      @height
   final
   # Hacerlos privados
   private :getWidth, :getHeight
 
   # Método de ejemplo para salida de área
   def printArea
      @area = getWidth() * getHeight
      puts "El área grande de la caja es: #@area"
   final
   # Hacer que el método de ejemplo sea protegido
   protected :printArea
final
 
# Create object
box = Box.new(10, 20)
 
# Call example method
a = box.getArea()
puts "Area of the box is: #{a}"
 
# Intentar llamar al método protegido de ejemplo
box.printArea()

Cuando se ejecuta el código anterior, se produce el siguiente resultado. Aquí, el primer método se llama con éxito, pero el segundo método produce un problema.

Area of the box is: 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height=20, @width=10> (NoMethodError)

la herencia de clases

herencia, que es una de las concepciones más importantes de la programación orientada a objetos. La herencia permite definir una clase basada en otra clase, lo que facilita la creación y el mantenimiento de aplicaciones.

La herencia ayuda a reutilizar código y a ejecutarlo rápidamente, desafortunadamente, Ruby no admite la herencia múltiple, pero Ruby admite mixins.

Cuando se crea una clase, el programador puede especificar directamente que la nueva clase herede los miembros de una clase existente, lo que permite evitar la escritura desde cero de nuevos miembros de datos y funciones de miembros. Esta clase existente se llamaclase base o clase padre, el nuevo tipo de clase se llamasubclase o subclase.

Ruby también ofrece el concepto de subclase, que es la herencia, el siguiente ejemplo explica este concepto. La sintaxis para extender una clase es muy sencilla. Basta con agregar un < seguido del nombre de la clase padre a la declaración de la clase. Por ejemplo, la siguiente declaración define la clase BigBox es Box la subclase de

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
   # Example method
   def getArea
      @width * @height
   final
final
 
# Definir subclase
class BigBox < Box
 
   # Agregar un nuevo método de ejemplo
   def printArea
      @area = @width * @height
      puts "El área grande de la caja es: #@area"
   final
final
 
# Create object
box = BigBox.new(10, 20)
 
# Imprimir área
box.printArea()

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

El área grande de la caja es: 200

sobre carga de métodos

Aunque puede agregar nuevas funcionalidades a la subclase, a veces es necesario cambiar el comportamiento de los métodos definidos en la clase padre. En este caso, puede mantener el nombre del método sin cambios y sobrecargar su funcionalidad, como se muestra en el siguiente ejemplo:

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
   # Example method
   def getArea
      @width * @height
   final
final
 
# Definir subclase
class BigBox < Box
 
   # Cambiar el método existente getArea
   def getArea
      @area = @width * @height
      puts "El área grande de la caja es: #@area"
   final
final
 
# Create object
box = BigBox.new(10, 20)
 
# Uso del método sobrecargado para calcular el área
box.getArea()

El resultado de ejecutar el ejemplo anterior es:

El área grande de la caja es: 200

sobre carga de operadores

Esperamos utilizar + operador realiza la adición vectorial entre dos objetos Box, utilizando * operador para multiplicar el ancho y la altura de Box, utilizando operadores unarios - A continuación, se muestra una versión de la clase Box con la definición de operadores matemáticos:

class Box
  def initialize(w,h) # Inicializar width y height
    @width, @height = w, h
  final
 
  def +(other)                           # Definir + para realizar la adición vectorial
    Box.new(@width + other.width, @height + other.height)
  final
 
  def -@                                                   # Definir un operador unario - para calcular el inverso de width y height
    Box.new(-@width, -@height)
  final
 
  def *(scalar)        # Ejecutar multiplicación escalar
    Box.new(@width*scalar, @height*scalar)
  final
final

congelar el objeto

A veces, queremos evitar que un objeto se cambie. En Object, el método freeze puede lograr esto, convirtiendo efectivamente un objeto en una constante. Cualquier objeto puede ser congelado llamando Object.freeze para congelar. Los objetos congelados no pueden ser modificados, es decir, no se puede cambiar sus variables de ejemplo.

Puede usar Object.frozen? El método verifica si un objeto dado ya ha sido congelado. Si el objeto ya ha sido congelado, este método devuelve true, de lo contrario devuelve un valor false. A continuación se explica este concepto con un ejemplo:

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
 
   # Métodos de acceso
   def getWidth
      @width
   final
   def getHeight
      @height
   final
 
   # Métodos de configuración
   def setWidth=(value)
      @width = value
   final
   def setHeight=(value)
      @height = value
   final
final
 
# Create object
box = Box.new(10, 20)
 
# Vamos a congelar el objeto
box.freeze
if( box.frozen? )
   puts "El objeto de Box es un objeto congelado"
else
   puts "El objeto de Box es un objeto normal"
final
 
# Ahora intenta usar métodos de configuración
box.setWidth = 30
box.setHeight = 50
 
# Uso de métodos de acceso
x = box.getWidth()
y = box.getHeight()
 
puts "El ancho de la caja es: #{x}"
puts "La altura de la caja es: #{y}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

El objeto de Box es un objeto congelado
test.rb:20:in `setWidth=': no se puede modificar un objeto congelado (TypeError)
        from test.rb:39

Constantes de clase

Puede definir una constante dentro de la clase, asignando un valor numérico o de cadena directo a una variable para definirla. La definición de constante no requiere el uso de @ o @@. De acuerdo con la convención, el nombre de las constantes se usa en mayúsculas.

Una vez que se define un constante, no se puede cambiar su valor, puede acceder a la constante dentro de la clase directamente, como si fuera una variable, pero si desea acceder a la constante desde fuera de la clase, debe usar classname::constant,如下面示例所示。

Ejemplos en línea

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

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

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.

Use allocate to create an object

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

Ejemplos en línea

#!/usr/bin/ruby -w
 
# Define class
class Box
   attr_accessor :width, :height
 
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   final
 
   # Example method
   def getArea
      @width * @height
   final
final
 
# Use new to create an object
box1 = Box.new(10, 20)
 
# Use allocate to create another object
box2 = Box.allocate
 
# Use box1 Call example method
a = box1.getArea()
puts "Area of the box is: #{a}"
 
# Use box2 Call example method
a = box2.getArea()
puts "Area of the box is: #{a}"

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

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 the example method, 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:.

Ejemplos en línea

#!/usr/bin/ruby -w
 
class Box
   # Salida de información de clase
   puts "Clase de self = #{self.class}"
   puts "Nombre de self = #{self.name}"
final

Cuando se ejecuta el código anterior, se producirá el siguiente resultado:

Clase de self = Class
Nombre de self = Box

Esto significa que la definición de la clase se puede ejecutar al hacer que la clase sea el objeto actual, también significa que el método en el metaclase y la clase padre está disponible durante la ejecución de la definición del método.