Ruby Orientado a objetos
Ruby es un lenguaje puramente orientado a objetos; todo en Ruby se presenta en forma de objetos. Cada valor en Ruby es un objeto, incluso las cosas más primitivas: cadenas, números, e incluso true y false son objetos. La clase en sí misma también es unobjeto, que esClassuna instancia de la clase. Este capítulo le explicará todas las características principales relacionadas con la orientación a objetos de Ruby.
Las clases se utilizan para especificar la forma de los objetos; combinan representación de datos y métodos, organizando los datos en un paquete ordenado. Los datos y métodos dentro de una clase se denominan miembros de la clase.
Definición de clases en Ruby
Cuando define una clase, en realidad está definiendo el plano de un tipo de datos. Esto no define ningún dato en sí, sino que define qué significa el nombre de la clase, es decir, de qué estará compuesto el objeto de la clase y qué operaciones se pueden realizar sobre dicho objeto.
La definición de una clase comienza con la palabra claveclass, seguida delnombre de la clase, y finalmente termina con unendpara indicar la finalización de la definición de la clase. Por ejemplo, usamos la palabra clave class para definir la clase Box, como se muestra a continuación:
Según la convención, el nombre debe comenzar con una letra mayúscula. Si contiene varias palabras, cada palabra debe comenzar con mayúscula, pero sin separadores entre ellas (por ejemplo: CamelCase).
Definición de objetos Ruby
Las clases proporcionan el plano de los objetos, por lo que básicamente los objetos se crean a partir de las clases. Usamos lanewpalabra clave para declarar objetos de la clase. La siguiente declaración declara dos objetos de la clase Box:
El método initialize
initializees un método de clase estándar de Ruby, es el constructor de la clase, similar alconstructorconstructor en otros lenguajes de programación orientada a objetos. Cuando se desea inicializar algunas variables de clase al crear el objeto, el método initialize resulta útil. Este método acepta una serie de parámetros y, al igual que otros métodos de Ruby, al usarlo debe colocarse delantedefla palabra clave, como se muestra a continuación:
Variables de instancia
Las variables de instanciason atributos de la clase; cuando se crea un objeto con la clase, se convierten en atributos del objeto. Los atributos de cada objeto se asignan por separado y no se comparten valores con otros objetos. Dentro de la clase, estos atributos se acceden mediante el operador @; fuera de la clase, se accede mediante los llamadosmétodos de accesodepúblicospara acceder. A continuación, la clase definida anteriormenteBoxA continuación, la clase definida anteriormente
Métodos de acceso (getter) y establecedores (setter)
Métodos de acceso (getter) y establecedores (setter)
Ejemplo
Alto de la caja : #{y}
Pruébalo »
盒子宽度 : 10 盒子高度 : 20
Cuando se ejecuta el código anterior, produce el siguiente resultado:De manera similar a los métodos de acceso que se usan para acceder al valor de las variables, Ruby proporciona una forma de pasar parámetros desde fuera de la clase a las variables ya definidas en la clase, es decir, los llamadosmétodos establecedores (setter)
Ejemplo
Alto de la caja : #{y}
Pruébalo »
盒子宽度 : 30 盒子高度 : 50
Cuando se ejecuta el código anterior, produce el siguiente resultado:attr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_nameDebido a que ambos métodos son muy comunes, Ruby defineaccessor=reader+writer。
tres métodos para declarar atributos. Entre ellos::Tenga también en cuenta: el nombre de la variable debe ir precedido de,@, y entre los nombres de las variables se debe usar
Métodos de instancia
Métodos de instanciaLos métodos de instanciadefse definen igual que los demás métodos, utilizando la
Ejemplo
Llamar al método de instancia
Pruébalo »
Area of the box is : 200
Métodos de clase y variables de clase
Métodos de clase y variables de claseLas variables de clase
son variables compartidas por todas las instancias de la clase. En otras palabras, una variable de clase puede ser accedida por todas las instancias de objetos. Las variables de clase llevan como prefijo dos caracteres @ (@@) y deben inicializarse en la definición de la clase, como se muestra en el siguiente ejemplo.Los métodos de clasedef self.methodname()se definen usandoclassname.methodnamedef, y terminan con el delimitador end. Los métodos de clase se pueden invocar usando la forma
Ejemplo
Llamar al método de clase para mostrar el contador de cajas
Pruébalo »
Box count is : 2
El método to_s
El método to_sto_sCualquier clase que defina tiene un
Ejemplo
Llamar automáticamente al método to_s
Pruébalo »
String representation of box is : (w:10,h:20)
Control de acceso
Control de accesoRuby le ofrece tres niveles de protección para los métodos de instancia, que sonpublic, private o protected
- . Ruby no aplica ningún control de acceso a las variables de instancia ni de clase.Métodos public:
- Los métodos public pueden ser llamados por cualquier objeto. Por defecto, todos los métodos son public, excepto el método initialize, que siempre es private.Métodos private:
- Los métodos private no pueden accederse ni verse desde fuera de la clase. Solo los métodos de la clase pueden acceder a los miembros privados.Métodos protected:
Los métodos protected solo pueden ser invocados por objetos de la clase y sus subclases. El acceso también solo puede realizarse dentro de la clase y sus subclases.
Ejemplo
Intentar llamar al método de instancia protected
Pruébalo »
Area of the box is : 200 test.rb:42: protected method `printArea' called for # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
Herencia de clases
La herencia es uno de los conceptos más importantes en la programación orientada a objetos. La herencia nos permite definir una clase basándonos en otra clase, lo que facilita la creación y el mantenimiento de aplicaciones.
La herencia ayuda a reutilizar código y a ejecutar rápidamente. Desafortunadamente, Ruby no admite la herencia múltiple, pero Ruby admitemixinsmixins. Los mixins son como una implementación específica de la herencia múltiple, en la que solo la parte de la interfaz es heredable.
Al crear una clase, el programador puede especificar directamente que la nueva clase herede los miembros de una clase existente, evitando así tener que escribir nuevos miembros de datos y funciones miembro desde cero. Esta clase existente se denominaclase base o clase padre, y la nueva clase se denominaclase derivada o subclase。
Ruby también proporciona el concepto de subclasificación, que es la herencia. El siguiente ejemplo explica este concepto. La sintaxis para extender una clase es muy sencilla. Solo hay que añadir un carácter < y el nombre de la clase padre a la declaración de la clase. Por ejemplo, a continuación se define la claseBigBoxSíBoxsubclase de:
Ejemplo
Pruébalo »
Cuando se ejecuta el código anterior, produce el siguiente resultado:
Big box area is : 200
Sobrecarga de métodos
Aunque puede añadir nuevas funcionalidades en la clase derivada, a veces es posible que desee cambiar el comportamiento de un método ya definido en la clase padre. En este caso, puede mantener el nombre del método sin cambios y sobrescribir la funcionalidad del método, como se muestra en el siguiente ejemplo:
Ejemplo
Pruébalo »
El resultado de ejecutar el ejemplo anterior es:
Big box area is : 200
Sobrecarga de operadores
Queremos usar el operador + para realizar la suma vectorial de dos objetos Box, usar el operador * para multiplicar el ancho y la altura de Box, y usar el operador unario - para negar el ancho y la altura de Box. A continuación se muestra una versión de la clase Box con definiciones de operadores matemáticos:
Congelar objetos
A veces, queremos evitar que un objeto sea modificado. En Object, el método freeze puede lograr esto, convirtiendo efectivamente un objeto en una constante. Cualquier objeto puede ser congelado llamando aObject.freezepara congelarlo. Un objeto congelado no puede ser modificado, es decir, no se pueden cambiar sus variables de instancia.
Puede usar elObject.frozen?método para comprobar si un objeto dado ya está congelado. Si el objeto está congelado, el método devuelve true; de lo contrario, devuelve false. El siguiente ejemplo explica este concepto:
Ejemplo
Pruébalo »
Cuando se ejecuta el código anterior, produce el siguiente resultado:
Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (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. La definición de una constante no requiere el uso de @ o @@. Por convención, los nombres de las constantes se escriben en mayúsculas.
Una vez que una constante está definida, no puede cambiar su valor. Puede acceder a la constante directamente dentro de la clase, como si fuera una variable, pero si desea acceder a la constante desde fuera de la clase, debe usarclassname::constant, como se muestra en el siguiente ejemplo.
Ejemplo
Pruébalo »
Cuando se ejecuta el código anterior, produce el siguiente resultado:
Area of the box is : 200 TATA Inc Box weight is: 10
Las constantes de clase pueden ser heredadas y también pueden sobrescribirse como los métodos de instancia.
Crear objetos con allocate
Puede haber una situación en la que desee crear un objeto sin llamar al constructor del objeto,initializees decir, sin usar el método new para crear un objeto. En este caso, puede llamar a allocate para crear un objeto no inicializado, como se muestra en el siguiente ejemplo:
Ejemplo
Pruébalo »
Cuando se ejecuta el código anterior, produce 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
Información de la clase
El self de Ruby tiene similitudes con el this de Java, pero también es muy diferente. En Java, los métodos se referencian dentro de métodos de instancia, por lo que this normalmente apunta al objeto actual. En Ruby, el código se ejecuta línea por línea, por lo que en diferentes contextos, self tiene diferentes significados. Veamos el siguiente ejemplo:
Ejemplo
Pruébalo »
Cuando se ejecuta el código anterior, produce el siguiente resultado:
Class of self = Class Name of self = Box
Esto significa que la definición de la clase se puede ejecutar teniendo la clase como objeto actual, y también significa que ese método en la metaclase y la clase padre está disponible durante la ejecución de la definición del método.
Otras extensiones