=begin
# 这章主要是说下ruby的model 类 方法 实例变量
Ruby语言中,任何的事物都是对象(Object),包含:模块(Model)、类(Class)、方法(Method)、实例变量(Instance Variables)等。
下面我们就逐个的来解释下这些对象在Ruby中是怎么样的一个存在?
实例变量(Instance Variables):
什么是实例变量那?
我们来看下他的定义?
1. 命名规则:以“@”开头;每个实例变量都是在第一次出现时动态加入对象;
2. 实例变量通常在方法中定义;
当在方法中声明实例变量时,该实例变量事实上属于该方法所在的类,而不是该方法;
虽然实例变量是属于类的,但大部分时候我们都是在该类的方法里定义实例变量;
3. Java在创建对象时一次为该对象的所有实例变量都分配了相应的内存空间;
Ruby语言里的对象完全是动态的,创建对象时该对象没有任何实例变量,直到执行到为实例变量定义时,该对象才动态增加该实例变量;
4. 生存范围:与该类对象的生存范围相同,只要该类对象存在,则该对象里的实例变量将一直存在;
但局部变量则会随着方法的消亡而消亡(除非使用闭包);
5. 实例变量的访问范围总是:private,即在类定义内对实例变量的赋值和读取没有限制;在类外访问实例变量时,则可以通过方法来访问;
6. 属性定义:1.用实例变量;2.用Module的方法(四个方法:attr,attr_reader,attr_writer,attr_accessor;示例:attr:color,true;);
7. 在模块中定义实例变量,目的是将该实例变量混入其他类中;(模块是无法创建实例的);
8. 类范围内定义的实例变量是Class对象的实例变量;
9. 实例变量永远都不能暴露为public,只能通过类方法(类名.方法名)暴露;
(注:摘自Blog-http://www.cnblogs.com/fanyangxi/articles/1632410.html)
从上面我们得出:
实例变量(Instance Variables)是当你使用它们时,才会被建立的对象.因此,即使是一个类的实例对象,也可以有不同的实例变量.
为什么同一个类的实例都共享类中的方法,却不能共享实例变量?
从技术层面上来看,一个对象(实例)只是存储了他的实例对象,并指向本实例的类。
因此,一个对象的实例变量仅存在于对象中,方法(我们称之为实例方法(Instance Methods))则存在于对象的类中。
String.instance_methods == "abc".methods # => true
String.methods == "abc".methods # => false
类(Class):
.类也是对象.因为类也是一个对象,能应用于对象的皆可运用于类。类和任何对象一样,有它们自己的类,Class类既是Class类的实例。
.像别的对象一样,类也有方法。对象的方法即是其所属类的实例方法。亦即,任何一个类的方法就是Class类的实例方法。
.所有的类有共同的祖先Object类(都是从Object类直接或间接继承而来),而Object类又继承自BasicObject类,Ruby类的根本。
.类名是常量(Constant)。
举个简单的例子来帮助你理解这些:
a. Classes Lei 因为一个类也是一个对象,所以一切适用于对象的也适用于类。 Classes,像其他任何对象一样也有自己的类。
String.class #=>Class
b. 像一切任何其他对象, classes也有方法, 类的方法也是它的类的实例方法(对象的方法即是其所属类的实例方法)。
这就意味着一个类的方法,也就是Class类的实例方法。
"string".methods == "string".class.instance_methods #=>true
c. 所有的类有共同的祖先Object类,我们来追本溯源看看他们。
Str=Class.new
p Str.ancestors =>[Str, Object, Kernel, BasicObject]
> Object.class => Class
> Class.superclass => Module
> Module.superclass => Object
> Object.superclass => nil
Object. Module, Class都是Class的实例对象。 而, Class的父类是Module, Module的父类是Object.
> Class.class.superclass.class #=> Class
Class是自己的实例。 Module, Object都是Class的实例, Class的超类又是Module, Object. ???
• Class继承自Object
• Object的class是Class
• Class的class是它自己
• 其它所有自定义class都是Class的object
• 其它所有自定义class都继承自Object
简单的说,就是,在继承层次上,所有class都继承自Object,同时,所有class都是Class的对象,
而Class又继承自 Object,因此所有class也都是Object的对象,结论:所有class既继承自Object,同时又是Object的对象。
Ruby里的MetaClass: metaclass就是定义其它class的class。
现在,我们已经知道:object(请注意:Ruby中的一切都是Object的对象)不能拥有方法。
但有些时候你可能想让一个object拥有它自己的方法,那该如何办呢,答案就是metaclass.
那么,普通的classes,以及object,都有自己的metaclass。参见:匿名类部分
Ruby Class是开放的,你可以重定义一个类,甚至于像String或Array这样的标准库中的类
例如:
class String
def str
"open class"
end
end
p String.new.str #=>"open class"
不过open classes的阴暗面, 可能会给类引入bug,比如重写了类已经有的同名方法。
模块(Module).
模块类似于类,
相同:他们都包含一组方法、常量、以及其他类和模块的定义。
区别:但不同的是不能创建模块的实例。模块不能生成实例,而类不能被include。
模块不可以有实体
模块不可以有子类:在类(模块)中include模块之后,就可实现类似于多重继承的Mix-in功能。
它与父类子类之间的这种直接继承关系有所不同,内含模块的类与该模块之间存在is_a?的关系。
模块由module...end定义.
实际上...模块的'模块类'是'类的类'这个类的父类。
模块用途有二?
一. 是扮演着命名空间的角色,使得方法的名字不会彼此冲突;
二. 是可以在不同的类之间共享同样的功能。通过模块能实现混合插入功能。
即:通过模块使用叫做混合插入的机制实现了多重继承
使用的时候,在class中使用include Module即可。
方法(Method):
方法的使用:
A. 使用一个点"."
B. 使用send方法来调用.使用send的这种ruby的技术叫做:“Dynamic Dispatch”
send()方法可以调用任何方法, 意味着对象的私有方法也可以通过send被调用。
具体参见:Ruby方法
=end
Model Class Method Instance Variables
最新推荐文章于 2022-07-27 14:42:28 发布