In the discussion of the object model, a preliminary understanding of the class, about the class itself, there is a lot of knowledge to learn.
Class definition
In Ruby, you can use the Class keyword or the Class.new method to define a class, in Ruby, the class definition is running code, classes and methods, blocks, and returns the value of the last statement, since the class is also an object (an instance of Class), So when a class defines an operation, the class itself acts as self:
result = Class MyClass
? ? Puts self
? ? "Return value"
End
Puts result
The above statement outputs:
MyClass
return value
Current class
The object invocation method requires a current object (self) as the receiver, how to get the current object? In Ruby, this class becomes the current class every time a class is opened by using class. In fact, if self is an object, then the current class is the class of that object. So in the top-level context, self = Main,main.class = object, so the current class is object.
In the previous essay, we know that we can use the context probe Object#instance_eval () method, which makes the called object Self and passes the block to access the modified object. In a class, there are similar methods: Module#class_eval (), the Class_eval () method makes the calling class the current class, and modifies the methods, properties in the added class. This method modifies the methods and properties of the class when the class name is unknown. The class keyword can use only constants as the class name, while Module#class_eval uses variables as the class name.
class instance variables and class variables
Class MyClass
? ? @var = 1
? ? def Self.read
? ? ? ? Puts @var
? ? End
? ? def read
? ? ? ? Puts @var
? ? End
? ? def write
? ? ? ? @var = 2
? ? End
End
obj = MyClass.New
Obj.write
Obj.read
Myclass.read
In the above code, when executing Obj.write, self is the Obj object, @var as an instance variable of obj, in obj, @var as the class instance variable of MyClass when executing myclass.read (emphasizing that the class is also an object, Myclass.class = class, so an instance variable is actually an instance variable of class object, exists in MyClass, and cannot be accessed by subclasses and instances.
If you want to define a variable in a class and you can inherit from a class, you need to use a class variable, which is a variable that starts with @@:
Class MyClass
? ? @ @var = 1
End
If you define a class variable @ @var, you can inherit the class variable from class MySubClass < MyClass classes.
A class variable has a problem that he does not belong to the class itself, but belongs to the class architecture:
@ @var = 1
Class MyClass
? ? @ @var = 2
End
Puts @ @var?
The code above will have a warning: Warning:class variable access from TopLevel?
Since @ @var = 1 executes, Self=main,main.class = object, so the @ @var belongs to object and all descendants of object, including MyClass, so using class variables in the top-level context is a risky behavior, while , you should also reduce the use of class variables and use class instance variables instead.
Class method
Because a class is also an object, a class can also invoke methods:
My_obj.my_method
Myclass.my_class_method
When an object invokes a method, it is actually a variable-referenced object that invokes the method, and when a class invokes a method, it is actually a constant-referenced object (an instance of Class) that invokes the method.
Before learning a dynamic call, use the self.define_component () to pass in a parameter as the method name and dynamically define the method:
Class computer
? ? def self.define_component (name)
? ? ? ? Define_method (name) {
? ? ? ? Puts "getting #{name} info"
? ? ? ? Puts "getting #{name} price"
? ? }
? ? End
? ? Define_component:mouse
? end
At this point, self is computer, so define_component is a class method, and the Define_component method can be called directly in computer, which is called a class macro.
Class macros are well-used in many places, such as adding a property to a class, you need to add a read method and a write method to manipulate an instance variable, so that the method definition repeats in many classes, using Module#attr_writer (), module# Attr_read (), Module#attr_accessor () can
Realize that the method of the object should be stored in the class, then the method of the class should be stored in class, that is, as the object inheriting from the class will have the class instance method, whether other classes will have this kind of method?
Class MyClass
? ? def Self.my_class_method
? ? ? ? "This is a Class_method"
? ? End
End
Class MyClass2
End
Puts MyClass.methods.grep (/my_class_method/)
Puts MyClass2.methods.grep (/my_class_method/)
Puts Class.instance_methods.grep (/my_class_method/)
In fact, the code above will only print a single line of "This is a Class_method", that is, the class method exists only in MyClass, not the class instance method, and is not inherited by other classes, so where is the class method stored?
single-piece method and single-piece class
In Ruby, the type of an object is a duck type, that is, the type of an object is not determined by his class, but rather depends on which methods it responds to. The object simply inherits the methods in the class, and similarly, he can have his own unique method, which is called a single-piece method: Singleton_methods. Since this method is unique to the object and does not exist in the class of the object, how is this single method called?
Each object has a hidden class: a single-piece class: Eigenclass, when an object has a single-piece method, it is looked up from the object's single-piece class, and the object's single-item class inherits from the object's class, so if it cannot be found in a single-piece class, it naturally looks from the parent class, the object's class. It is then looked up from the ancestor chain in the same way as the normal method, until it is found, or not found, to call Missing_method.
Class is also an object, so there is a single-piece class method, so the class also has a eigenclass, and the Eigenclass parent class is the eigenclass of the parent class, so the class method can be called by the class, but it cannot be accessed by other classes.
Eigenclass is also a class, so Eigenclass also has a eigenclass.
In Ruby, you can access one-piece classes in the following ways:
Class << MyClass
? ? def My_singleton_class
? ? End
End
At the same time, MyClass if obj is a single-piece method for an object, class << represents the one-piece class that needs to be accessed.
Knowing this, you can add attributes to the class as well. The property of an object is to read and write to an instance variable of an object, and the property of the class is to read and write to the class instance object and implement it with a class macro:
Class MyClass
? ? Attr_accessor:a
? ? Class << Self
? ? ? ? Attr_accessor:b
? ? End
? end?
Now, MyClass has an instance property A, and has a class attribute B, and the property is not accessed by other classes and disrupts the entire namespace, which is inherited by the quilt class.
Through the module can add some packaged class instance method, then how to Add Class method through the module ?
Class MyClass
? ? Include MyModule1
? ? Class << Self
? ? ? ? Include MyModule2
? ? End
End
At this point, the method in MyModule1 is added as an instance method in MyClass, and the method in MyModule2 is added as a class method. This kind of application is quite common, so there are object#extend () methods to deal with these problems specifically:
Class MyClass
? ? Extend MyModule2
End
obj = MyClass.New
Obj.extend MyModule1
The Extend method actually contains a shortcut to the module in the recipient's eigenclass.
AliasThe alias keyword allows you to add an alias to the method, Alias:another_name:my_method, noting that there is no comma in the middle because alias is a keyword and not a method (where is the keyword in the structure, and what is the difference between the method)? )。 When a new name is called, the original method is called when the alias is added.
The method that is named after the alias is redefined, then the alias method refers to the original method, according to this feature, you can implement the technique of wrapping aliases:
Class MyClass
? ? Alias:real_length:length
? ? def length
? ? ? ? Real_length > 5? ' Long ': ' Short '
? ? End
End
When the Myclass#length method calls the alias Real_length, it actually calls the original length method, which is somewhat similar to the protected field used in assembly language, and is versioned with surround aliases in gems. Surround aliases are a monkey patch that can cause conflicting issues, especially when used.
The deep class of Ruby learning