Classes are the basic template from which object instances are created. A class is made up of a collection of variables representing internal state and methods providing behaviours that operate on that state.
在个体导向(object-oriented)的世界中，每个事物，如太阳、月亮、文件、目录、储存体、你、我、他等等，都视为独立个体(objects)。我们又将这些独立个体按其属性、行为抽象化地分门别类，于是有了各种类(classes)。我们称归属于某一类的个体为该类的实例(instance)，例如我家养的小黄狗，就是狗类的一个实例。在某些程式语言中，个体与实例的差别不明显，初学者常分不清两者意义。但是，在 Ruby 之中一切都是个体，举凡字面值、函数及类别等等，都是个体；而实例仅仅指我们向 Ruby 要求配置的某一类别之实体化的个体，而不指涉类、字面值等个体。
class 定义'类(Class)'的内容。类的名称必须按 camel 惯例命令，此为基于英文系统之命令惯例：以英文字(word) 组成名称，每个字的首字母皆作大写，而且每个字必须相接不可以分隔字元分开。例如 'MyClass', 'BasicSocket', 'DateTime'。类的定义内容包含方法与类别变数，以关键字
def方法名 #方法的程式區塊 end
class MyClass def some_method end end
class MyClass @one = 1 def do_something @one = 2 end def output puts @one end end instance = MyClass.new instance.output instance.do_something instance.output
This happens (nil in the first output line) because @one defined below class MyClass is a class instance variable(?), whereas @one defined inside do_something method is a variable of object instance. They are two distinct variables and the first is accessible only in a method of a class(?).
Class variables are accessed using the @@ operator. These variables are associated with the class rather than any object instance of the class and are the same across all object instances. (These are the same as class "static" variables in Java or C++).
class MyClass @@value = 1 def add_one @@value= @@value + 1 end def value @@value end end instanceOne = MyClass.new instanceTwo = MyClass.new puts instanceOne.value instanceOne.add_one puts instanceOne.value puts instanceTwo.value
1 2 2
Be careful when you use class variables though. They can sometimes lead to an additional debug time, thus I'd advise you to only use them when it is absolutely necessary to use them.
Class methods are declared the same way as normal methods, except that they are prefixed by
self followed by a period. These methods are executed at the Class level and may be called without an object instance. They cannot access instance variables but do have access to class variables.
class MyClass def self.some_method puts 'something' end end MyClass.some_method
An object instance is created from a class through the a process called instantiation. In Ruby this takes place through the Class method
anObject = MyClass.new(parameters)
This function sets up the object in memory and then delegates control to the initialize function of the class if it is present. Parameters passed to the new function are passed into the
class MyClass def initialize(parameters) end end
所有的方法默认的都是公开的，可被所有对象调用。需要的时候可以用 public, private 和 protected 加以限制。有趣的是这些并不是关键字，而仅仅是对类本身进行操作方法，他们可以动态的改变方法的可见度。
class Example def methodA end private # all methods that follow will be made private: not accessible for outside objects def methodP end end
如果 private 没有跟任何参数, 它后续的所有方法都变成私有。如果有参数，则指明的方法变为私有。
Named private method example:
class Example def methodA end def methodP end private :methodP end
Here private was invoked with an argument, altering the visibility of methodP to private.
注意如果是类的方法（静态方法，按照 def ClassName.method_name 声明的), 则需要使用另外的方式: private_class_method。
常见的用法是把 new 方法设定为私有，这样就可以实现唯一的实例。
class SingletonLike private_class_method :new def SingletonLike.create(*args, &block) @@inst = new(*args, &block) unless @@inst return @@inst end end
More info about the difference between C++ and Ruby private/protected: http://lylejohnson.name/blog/?p=5
One person summed up the distinctions by saying that in C++, “private” means “private to this class”, while in Ruby it means “private to this instance”. What this means, in C++ from code in class A, you can access any private method for any other object of type A. In Ruby, you can not: you can only access private methods for your instance of object, and not for any other object instance (of class A).
Ruby folks keep saying "private means you can not specify the receiver". What they are saying, if method is private, in your code you can say:
class AcessPrivate def a end private :a # a is private method def acessing_private a # sure! self.a # sure! same as above, because "self." prefix was implicit there other_object.a # nope, a is private, you can't get it (but if it was protected, you could!) end end
Here, "other_object" is the "receiver" that method "a" is invoked on. For private methods, it does not work. However, that is what "protected" visibility will allow.
Public is default accessibility level for class methods. I am not sure why this is specified - maybe for completeness, maybe so that you could dynamically make some method private at some point, and later - public.
In Ruby, visibility is completely dynamic. You can change method visibility at runtime!
Now, protected deserves more discussion. Those of you coming from Java (or C++) background, you know that "private" means that method visibility is restricted to the declaring class, and if method is "protected", it will be accessible for children of the class (classes that inherit from parent).
In Ruby, private visibility is what protected was in Java. Private methods in Ruby are accessible from children. This is a sensible design, since in Java, when method was private, it rendered it useless for children classes: making it a rule, that all methods should be "protected" by default, and never private. However, you can't have truly private methods in Ruby; you can't completely hide a method.
The difference between protected and private is subtle. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object instance's private methods directly, even if the object is of the same class as the caller. For protected methods, they are accessibe from objects of the same class (or children).
So, from within an object "a1" (an instance of Class A), you can call private methods only for instance of "a1" (self). And you can not call private methods of object "a2" (that also is of class A) - they are private to a2. But you can call protected methods of object "a2" since objects a1 and a2 are both of class A.
Ruby FAQ gives following example - implementing an operator that compares one internal variable with variable from another class (for purposes of comparing the objects):
def <=>(other) self.age <=> other.age end
If age is private, this method will not work, because other.age is not accessible. If "age" is protected, this will work fine, because self and other are of same class, and can access each other's protected methods.
To think of this, protected actually reminds me of the "internal" accessibility modifier in C# or "default" accessiblity in Java (when no accessibility keword is set on method or variable): method is accessible just as "public", but only for classes inside the same package.
实例变数存取子(Instance Variable Accessor)[编辑]
Note that object instance variables are not really private, you just can't see them. To access an instance variable, you need to create a getter and setter.
Like this (no, don't do this by hand! See below):
class GotAccessor def initialize(size) @size = size end def size @size end def size=(val) @size = val end end # you could the access @size variable as # a = GotAccessor.new(5) # x = a.size # a.size = y
Luckily, we got special functions to do just that: attr_accessor, attr_reader, attr_writer. attr_accessor will give you get/set functionality, reader will give only getter and writer will give only setter.
Now reduced to:
class GotAccessor def initialize(size) @size = size end attr_accessor :size end # attr_accessor generates variable @size accessor methods automatically: # a = GotAccessor.new(5) # x = a.size # a.size = y
一个类可以自'基础类(base class)' - 或称'父类(parent class)'或 'supperclass' - 继承方法与类别变数。Ruby 不支持'多重继承'，故一个类只有一个基础类。新的类可以再衍生更底层的类，而衍生的类总是拥有比基础类更丰富的方法，代代相承形成类别树而逐渐创造出行为丰富的世界。
在 Ruby 中，方法的预设可见度为
private。在继承行为中，衍生类不会承继基础类的 private 方法。
class ParentClass def a_method puts 'b' end end class SomeClass < ParentClass # < means inherit (or "extends" if you are from Java background) def another_method puts 'a' end end instance = SomeClass.new instance.another_method instance.a_method
If your class overrides a method from parent class (superclass), you still can access the parent's method by using 'super' keyword.
class ParentClass def a_method puts 'b' end end class SomeClass < ParentClass def a_method super puts 'a' end end instance = SomeClass.new instance.a_method
(because a_method also did invoke the method from parent class).
If you have a deep inheritance line, and still want to access some parent class (superclass) methods directly, you can't. super only gets you a direct parent's method. But there is a workaround! When inheriting from a class, you can alias parent class method to a different name. Then you can access methods by alias.
class X def foo "hello" end end class Y < X alias xFoo foo def foo xFoo + "y" end end puts X.new.foo puts Y.new.foo
老子有云：'有物混成，先天地生'。在 Ruby 之中，也有着混成(mix-in)的概念。Ruby 可以将行为自类抽离出来，使其成为与类或实例无关的抽象化行为。我们可以再将这些抽象化行为混成一个新的类，或令一个类包含更多种行为。
self。 Ruby 以关键字
module MixAlot def say_what? "hello" end end
class MC include MixAlot # ... method say_what? is available here! end
include 模组之前必须先以 require 叙述载入模组文件。
In keeping with the Ruby principle that everything is an object classes are themselves instances of the class Class. They are stored in constants under the scope of the module in which they are declared. A call to a method on an object instance is delegated to a variable inside the object that contains a reference to the class of that object. The method implementation exists on the Class instance object itself. Class methods are implemented on meta-classes that are linked to the existing class instance objects in the same way that those classes instances are linked to them. These meta-classes are hidden from most Ruby functions.