Ruby Programming Language学习笔记之对象、类、模块(初稿)

对象、类、模块

1.1、封装

1.1.1类层次结构

Object:顶级类
Kernel:mix-in到Object中的模块
Class:产生类对象的类

Module Module是Class的父类

Classes, modules, and objects are interrelated. In the diagram that follows, the vertical arrows represent inheritance, and the parentheses meta-classes. All metaclasses are instances of the class `Class ’.

                          +------------------+
                          |                  |
            Object---->(Object)              |
             ^  ^        ^  ^                |
             |  |        |  |                |
             |  |  +-----+  +---------+      |
             |  |  |                  |      |
             |  +-----------+         |      |
             |     |        |         |      |
      +------+     |     Module--->(Module)  |
      |            |        ^         ^      |
 OtherClass-->(OtherClass)  |         |      |
                            |         |      |
                          Class---->(Class)  |
                            ^                |
                            |                |
                            +----------------+



1.1.2总论

Ruby所有的东西都是对象,而每个对象都是某个类的实例。类本身也是对象,称为类对象。既然类是对象,那么产生类对象的类是什么呢,就是Class类。
类对象有自己的方法、状态和ID。它不与它的实例分享这些信息。这一点与Java不同,Java中的static变量/方法就是类变量/方法,它们是类和类的所有实例共享的。


模块与类的主要区别是:不能实例化、不能继承(可以互相mix-in)
类可以mix-in多个module,但只能有一个父类

对象/类/模块都可以被重新打开,添加内容。打开类/模块与定义它们是一样的,但打开对象就需要用<<
可以给对象添加方法,称为singleton method(不推荐如此)。而在类中编写、可被类的所有实例使用的方法称为实例方法。

实体或事物最好建模为类,而实体说事物的特性或行为最好建模为模块。因此倾向于用名称作为类名,而用形容词作为模块名。
module的思想类似AOP(面向切面编程)。

module和class可以互相多层嵌套,用::引用,此时module和class的作用相当于namespace。





1.1.3类

类方法(类实例方法)
定义类方法用<<符号,以下是重新打开一个类
class << Point
     def class_method1      # This is an instance method of the eigenclass.
     end                               # It is also a class method of Point.
     def class_method2
     end
end
如果是在类定义的时候则可以这样
class Point
     # instance methods go here
     class << self
         # class methods go here as instance methods of the eigenclass
     end

    def Point.class_method1
    end

    def this.class_method2
    end

end
下面2种方法是一样的,这说明<<用于向对象添加方法 ,这个对象包括类对象和普通对象。
obj = T1.new

def obj.test
....
end

class << obj
....
end

类实例变量 :在类定义中定义的@variable_name

class Point
     # Initialize our class instance variables in the class definition itself
     @n = 0 # How many points have been created
     @totalX = 0 # The sum of all X coordinates
     @totalY = 0 # The sum of all Y coordinates

     def initialize(x,y) # Initialize method
         @x,@y = x, y # Sets initial values for instance variables
     end

     def self.new(x,y) # Class method to create new Point objects
          # Use the class instance variables in this class method to collect data
          @n += 1 # Keep track of how many Points have been created
         @totalX += x # Add these coordinates to the totals
         @totalY += y
         super # Invoke the real definition of new to create a Point
         # More about super later in the chapter
     end

     # A class method to report the data we collected
     def self.report
          # Here we use the class instance variables in a class method
          puts "Number of points created: #@n"
          puts "Average X coordinate: #{@totalX.to_f/@n}"
          puts "Average Y coordinate: #{@totalY.to_f/@n}"
     end
end


类变量
:@@variable_name
类变量一般直接在类中定义,而不在任何方法中定义;对与类方法和实例方法都是可见的。
class Point
     # Initialize our class variables in the class definition itself
     @@n = 0 # How many points have been created
     @@totalX = 0 # The sum of all X coordinates
     @@totalY = 0 # The sum of all Y coordinates
   
     def initialize(x,y) # Initialize method
          @x,@y = x, y # Sets initial values for instance variables
          # Use the class variables in this instance method to collect data
          @@n += 1 # Keep track of how many Points have been created
          @@totalX += x # Add these coordinates to the totals
          @@totalY += y
     end

     # A class method to report the data we collected
     def self.report
         # Here we use the class variables in a class method
        puts "Number of points created: #@@n"
          puts "Average X coordinate: #{@@totalX.to_f/@@n}"
          puts "Average Y coordinate: #{@@totalY.to_f/@@n}"
     end
end

类(实例)方法是类对象独有的,类实例变量也是类对象独有的,只有类(实例)方法可以访问。
类变量是类及其所有实例共有的。

实例方法:

实例变量: 在实例方法中定义的@variable_name,一般在initialize方法中初始化。

单例方法: 对象特有的(而不是在类中定义的)方法

常量: 给常量名重新赋值和修改常量所引用的对象,这个差别非常重要。Ruby中存在2中改变:改变标识符到对象的映射,改变对象的内容或状态。对于常量来说,前者是可以的,但会引起警告,也是不推荐的。后者则是完全没有问题的。
常量用::引用


1.1.4模块

Module是模块方法、实例方法、常量(类和模块也是常量)和类变量(@@variable_name)的集合。
A module is a named group of methods, constants, and class variables.

当一个类include一个模块的时候,模块的实例方法可见,模块的模块方法不可见。相反的,调用模块方法的语法是Module::method,而要调用模块的实例方法则必须通过include该模块的类的具体实例来调用。
A Module is a collection of methods and constants . The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included , module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function )

模块方法

module Base64
     def self.encode
     end

     def self.decode
     end
end
或者
module Base64
     def Base64.encode
     end

     def Base64.decode
     end
end

实例方法
module Base64
     def encode
     end

     def decode
     end
end

1.1.5对象

生成一个对象
obj=Object.new

给对象定义行为
def obj.talk
end
或者
class << obj
    def talk
    end
end
这些方法叫做单例方法。

1.1.6方法可见性

public/protected/private
ruby中的可见性只针对method 。变量统一都是private的,常量统一都是public的,它们没有可见性这一说。

对实例变量来说,它并不是在类定义中创建的,它是在运行时首次被赋值的时候创建的。它超脱于类之外,只是附着在运行时对象上,因此不能用public/protected/private这些编译时的方法来限定它。同事实例变量也不在类的继承体系中。原因相同。

public/protected/private都是在Module类中的方法,它们不是关键字 。它们可以在Class和Module 中使用,但不能在Object中使用。也就是说我们通过:
class << obj
    def talk
    end
end
添加单例方法时不能使用public/protected/private

public
默认

private
对实例方法可见
对于private方法m,任何时候都只能用m调用,不能用o.m或self.m调用

protected
对于protected方法m,任何时候都可以用m或o.m或self.m调用,因此常用于同一个类的不同实例之间互相访问数据。原理如下
A protected method defined by a class C may be invoked on an object o by a method in an object p if and only if the classes of o and p are both subclasses of, or equal to, the class C.

private_class_method
public_class_method

用于处理类方法的可见性问题

1.2、继承

方法搜索的顺序:当前类-->当前类mix-in的module(与声明顺序相反)-->父类-->父类类mix-in的module(与声明顺序相反)
super:获取并执行在方法查找路径上下一个 匹配该方法的名的方法。对类方法和实例方法同样有效。
this

public/protected/private的方法都会被继承(与Java不同)

实例方法 :继承

实例变量: 不继承。实例变量超脱于类及其继承体系之外。
对实例变量来说,它并不是在类定义中创建的,每一个对象都有一个实例变量集,集合中的实例变量是在运行时首次被赋值的时候创建的。它超脱于类及其继承体系 之外,是完全的运行时概念,只是附着在运行时对象上。有时实例变量看起来是被继承了的,这只是表面现象,内在的原因是实例变量在某些方法中被首次赋值从而 被创建,而这些方法被继承了,所以看起来像是实例变量也被继承了。代码如下:
class Point3D < Point
     def initialize(x,y,z)
          super(x,y)
          @z = z;
     end

     def to_s
          "(#@x, #@y, #@z)" # Variables @x and @y inherited?
     end
end

Point3D.new(1,2,3).to_s # => "(1, 2, 3)"

类方法 :继承

类变量: 继承
在定义该类变量的类及其所有子类中共享同一个变量。

常量: 继承
如果子类常量与父类常量同名,则子类和父类都会单独拥有2个常量,如:
Point::ORIGIN and Point3D::ORIGIN


抽象类:父类中可引用尚未实现的子类方法。
# This class is abstract; it doesn't define greeting or who
# No special syntax is required: any class that invokes methods that are
# intended for a subclass to implement is abstract.
class AbstractGreeter
     def greet
          puts "#{greeting} #{who}"
     end
end

# A concrete subclass
class WorldGreeter < AbstractGreeter
     def greeting; "Hello"; end
     def who; "World"; end
end

WorldGreeter.new.greet # Displays "Hello World"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值