Acabo de empezar a jugar con JRuby. Este es mi primer post Ruby. Me costó entender las clases y los objetos en Ruby. No significa como clases y objetos en otros idiomas orientados a objetos. para un ejemplo
Class.is_a? Object
devuelve verdadero y
Object.is_a? Object
tambien
así que clase y objeto son ambos objetos
aquí viene otro
Class.is_a? Class
devuelve verdadero y
Object.is_a? Class
tambien
espera, no he terminado todavía
Object.instance_of? Class Class.instance_of? Class
Ambos son verdad
Object.instance_of? Object Class.instance_of? Object
Ambos son falsos bien, nada puede ser instancia de objeto.
Y
Class.kind_of? Class Object.kind_of? Class
ambos son verdad
Class.kind_of? Object Object.kind_of? Object
ambos son verdad
Entonces, ambos son exactamente iguales, entonces ¿por qué tenemos ambos esto?
Después de algunas excavaciones más, escribí este método simple para devolver la lista de métodos soportada por ambos
irb(main):054:0> def print_methods(obj) irb(main):055:1> obj.methods.each do |mm| irb(main):056:2* puts mm irb(main):057:2> end irb(main):058:1> end
La única diferencia de método entre print_methods (Object) y print_methods (Class) es
Nesting
si Anidar significa herencia, ¿el Objeto es similar a la clase sellada?
¿Puede alguien aclararme qué es todo esto?
Actualización: A Edds comentar
Curiosamente veo muchas diferencias en la lista de métodos en
c=Class.new print_methods(c)
Y
o=Object.new print_methods(o)
Ahora entiendo que la instancia de una clase es realmente una instancia de clase (y esta instancia de clase es en realidad un objeto) no una instancia de objeto. E incluso esta instancia me permite abarcar otras instancias.
xx = c.new //works - c is an Object / and xx is a instance of an Object c yy = o.new //nope - o is already a instance of an Object, so it cannot be instantiated again
Así que finalmente, el objeto es realmente una instancia de una clase. Porque
xx.is_a? Class
es falso, pero
xx.is_a? Object
devuelve verdadero
Estoy en lo cierto ??
Básicamente, la clave a entender es que cada clase es una instancia de la clase y cada clase es una subclase de Object
(en 1.8 – en 1.9 cada clase es una subclase de BasicObject
). Así que cada clase es un objeto en el sentido de que es una instancia de una subclase de Object
, es decir, Class
.
Por supuesto, esto significa que la Class
es una instancia de sí misma. Si eso hace que te duela el cerebro, no lo pienses demasiado.
Object
y Class
son is_a? Object
is_a? Object
x.is_a? y
x.is_a? y
devuelve true
si x.class == y or x.class < y
, es decir, si la clase de x
es y
o la clase de x
hereda de y
. Dado que cada clase hereda del objeto x.is_a? Object
x.is_a? Object
devuelve verdadero sin importar lo que sea x
. (De todos modos, en 1.8, en 1.9 también está BasicObject
que ahora es la clase más básica en la jerarquía de herencia).
is_a? Class
is_a? Class
Tanto el Object
como la Class
son clases, por lo que no debería ser sorprendente.
instance_of? Class
instance_of? Class
, pero no instance_of? Object
instance_of? Object
A diferencia de is_a?
, x.instance_of? y
x.instance_of? y
solo devuelve verdadero si x.class == y
, no si x.class
es una subclase de y
. Entonces, ¿ya que tanto x
como y
son instance_of? Class
instance_of? Class
, no son de instance_of? Object
instance_of? Object
bien, nada puede ser instancia de objeto.
Eso no es cierto. Object.new.instance_of? Object
Object.new.instance_of? Object
es verdadero.
kind_of?
es un alias para is_a?
, así que ver más arriba.
Entonces, ambos son exactamente iguales, entonces ¿por qué tenemos ambos esto?
Cabe señalar que hasta ahora todo es cierto para todas las clases. Ej. String.is_a? Object
String.is_a? Object
, String.is_a? Class
String.is_a? Class
y String.instance_of? Class
String.instance_of? Class
son verdaderas y String.instance_of? Object
String.instance_of? Object
es falso por las mismas razones que arriba. (También String.is_a? String
y String.instance_of? String
son falsos por las mismas razones: String es una clase, no una cadena).
No se puede concluir de esto que todas las clases son iguales. Son solo todas las instancias de la misma clase.
Dado que tanto el Object
como la Class
son clases, ambos tienen todos los métodos de instancia definidos por la Class
. Class
adicionalmente tiene el método de nesting
singleton. nesting
le indica en qué módulo está nested actualmente, no tiene nada que ver con la herencia.
Para cualquier clase dada, TheClass.methods
devolverá los métodos de instancia definidos por Class
(por ejemplo, superclass
, que devuelve la clase de la cual TheClass
hereda, y new
que crea una nueva instancia de TheClass
) más los métodos singleton definidos por esa clase.
De todos modos, los methods
solo le dicen qué métodos se pueden llamar directamente en un objeto determinado. No le dice qué métodos se pueden llamar en una instancia de una clase. Para eso, puede usar instance_methods
, que devuelve resultados significativamente diferentes para Object
y Class
.
En Ruby, todo es un Object
incluyendo clases y módulos. Object
es la clase más baja (bueno, en Ruby 1.9.2 también hay BasicObject
pero esta es otra historia).
Vea la siguiente salida.
> Object.ancestors # => [Object, Kernel, BasicObject] > Class.ancestors # => [Class, Module, Object, Kernel, BasicObject] > Module.ancestors # => [Module, Object, Kernel, BasicObject] > String.ancestors # => [String, Comparable, Object, Kernel, BasicObject]
Como puede ver, tanto la Class
como el Module
heredan de Object
.
De vuelta a sus afirmaciones originales, usted tiene que entender la diferencia entre
is_a?
kind_of'
instance_of?
No son intercambiables. is_a?
y kind_of?
devuelve true si otro es la misma clase o un antepasado. A la inversa, instance_of?
devuelve true solo si otro es la misma clase.
> Class.is_a? Object # => true > Class.kind_of? Object # => true > Class.instance_of? Object # => false
Ramesh, en ruby todo es un objeto, y una clase no es una excepción.
prueba esto en irb
ruby-1.9.2-p136 :001 > o = Object.new => # ruby-1.9.2-p136 :002 > o.is_a? Class => false ruby-1.9.2-p136 :003 > o.is_a? Object => true
en este caso, he creado una instancia de un objeto y he comprobado si es una clase (falsa) o un objeto (verdadera).
Una clase en ruby es un tipo de objeto de plantilla que se utiliza para crear instancias de esa clase. Siento que esto no esté super claro. El concepto clave es que ruby es un lenguaje orientado a objetos puros, a diferencia de Java.
La jerarquía de clase / metaclase es siempre un poco desconcertante 🙂 Solo para comparación, aquí está la de Smalltalk ; en Ruby, la configuración se basa en los mismos principios, excepto que no tiene las distinciones de Behavior
y ClassDescription
, y hay módulos y eigenclasses para tener en cuenta.
Una explicación completa del modelo de objetos Smalltalk está disponible en Pharo por Ejemplo , como se señala en esta pregunta relacionada .
Como _por qué escribe en este artículo.
Los objetos no almacenan métodos, solo las clases pueden.
Las primeras secciones de pareja tienen algunos puntos positivos sobre las clases y los objetos.
Una de las respuestas menciona esto:
Básicamente, la clave a entender es que cada clase es una instancia de la clase y cada clase es una subclase de Object. Así que cada clase es un objeto en el sentido de que es una instancia de una subclase de Objeto, es decir, Clase.
Solo quiero expresslo de manera diferente para aquellos que tienen un pequeño giro cerebral. Primero pregúntate: ¿Qué es una instancia en la progtwigción? ¿Y qué es una subclase en progtwigción? Una instancia es solo una variación realizada de un plano (la Clase). Una subclase es simplemente una clase (modelo) que se hereda de otra clase (modelo). Entonces cuando creas una nueva clase:
class Apple end
Apple es una instancia de Clase, es decir, es una variación realizada del plano. Toma el plano y completa los detalles (métodos y variables) con su propia variación. Bueno, el plano se hereda de otro plano, que es Objeto. Así que cada clase es una instancia de Clase, que es una subclase de Objeto.
class A end A.parent => Object A.class => Class
Note: La clase tiene el módulo en su cadena de herencia (¿el módulo incluido en la clase como una combinación tal vez porque el padre de la clase es Object?).
A.is_a?(Module) => true
Las instancias (A.new) de la clase A tendrán sus propias variaciones realizadas de A. Pero son instancias de objetos. Por lo tanto, debemos distinguir instancias de clase (por ejemplo, final de clase A) e instancias de objeto (a = A.nuevo). Las instancias de objetos tienen una cadena de herencia diferente. Son una variación realizada de un modelo de instancia de clase, no una variación de clase de clase.
Esto significa que en su cadena de herencia no es Clase o Módulo. Pero más bien otras instancias de objeto, así que si A tiene instancias de objeto y B tiene instancias de objeto y A hereda de B, cuando instanciamos una nueva instancia de objeto de A, esta instancia tendrá instancias de B en su cadena de herencia.
También heredarán de Object, ya que todo en Ruby hereda de Object.
a = A.new => # a.is_a?(Class) => false a.is_a?(Module) => false a.is_a?(Object) => true
Y esta es la mejor manera de pensar en todo. No profundices demasiado con tu pensamiento. Acepta esto como lo he escrito.
Piense en las clases como objetos globales.