Ruby基础教程(三)——类和模块

来源:互联网 发布:中国云计算创新基地 编辑:程序博客网 时间:2024/05/16 10:36

三、类和模块

  1. 什么是类

    • 类表示对象的种类。Ruby是完全面向对象的语言,一切都是对象,某个对象必属于某个类

    • class方法——给出某个对象所属的类

    ary = []a = 1s = "string"p ary.class #==>Arrayp a.class   #==>Fixnump s.class   #==>String
    • instance_of?方法——判断对象是否是给定类的一个实例
    ary = []p ary.instance_of?(Array)   #==> truep ary.instance_of?(String)  #==> falsep ary.instance_of?(Object)  #==> false   虽然Object是ary的父类,但ary不是Object的实例
  2. 继承

    2.1 继承的作用

    • 在不影响原有功能的前提下追加新功能

    • 重定义原有功能,使名称相同的方法产生不同的效果

    • 在已有功能的基础上追加处理,扩展已有的功能

    2.2 BasicObject类

    • BasicObject类是Ruby中所有类的父类

    • BasicObject类是最基础的类,只定义了最基础的方法。普通对象一般都是继承Object类

      BasicObject
      |
      |==========Object
      |==========|
      |==========|==========Array
      |==========|==========String
      |==========|==========Hash
      |==========|==========IO
      |==========|==========|
      |==========|==========|==========File
      |==========|==========Regexp
      |==========|==========Dir
      |==========|==========Numeric
      |==========|==========|
      |==========|==========|==========Integer
      |==========|==========|==========|
      |==========|==========|==========|==========Fixnum
      |==========|==========|==========|==========Bignum
      |==========|==========|==========Float
      |==========|==========|==========Complex
      |==========|==========|==========Rational
      |==========|==========Exception
      |==========|==========Time

    • is_a?方法——判断对象是否属于给定的类

      ary = []p ary.instance_of?(Array)   #==> truep ary.instance_of?(String)  #==> falsep ary.instance_of?(Object)  #==> true   Object是ary的父类
  3. 创建类

    • 类名首字母必须大写

      class 类名    类的定义end
    • initialize方法

      使用new方法创建对象时,initialize方法会被调用,new的参数会传给initialize方法

    def initialize(myname = "Ruby" )    @name = mynameend
    • 实例变量

      实例变量,就是类的成员变量,以“ @ ”开头

      引用未初始化的实例变量时,返回值为nil

    • 存取器

      从对象外部不能直接访问实例变量,需要通过方法来完成

    def name    @nameenddef name= (value)    @name = valueendp bob.name              #==> 获取name的值p bob.name = "David"    #==> 调用name=方法,像赋值一样
    • 如果变量太多,每个变量都定义存取方法太麻烦,可以使用方法attr_reader, attr_write, attr_accessor
    定义 意义 attr_reader 只读 attr_write 只写 attr_accessor 读写
    class HelloWorld    attr_reader :name    attr_writer :address    attr_accessor :phoneend
    • 特殊变量self

    相当于C++的this

    class Test    attr_accessor :name    def initialize(str = "David")        @name = str    end    def show1        name = "XXX"        p @name        p name    end    def show2        p self.name    endendt = Test.new()t.show1 #==> "David"        #==> "XXX"t.show2 #==> "David"
  4. 类方法

    方法的接收者为类本身,称为类方法

    • 方法1

      class << HelloWorld    class << self        def classFunc1(XXX)   #==> 在类HelloWorld中,定义类方法            ...        end        def classFunc2(XXX)            ...        end    endend
    • 方法2

      class Testenddef Test.show    p "show"endTest.show   #==>  "show"
    • 方法3

      class << Test    def show        p "show"    endendTest.show   #==> "show"
  5. 常量

    需要用::访问

    class Test    Version = "1.0"endp Test::Version #==> "1.0"
  6. 类变量

    类变量以@@开头

    类变量被类的所有实例共享

    class Test    @@cnt = 0end
  7. 限制方法

    public 全员公开(默认)

    private 对外不公开,只有内部的方法能够调用

    protected 内部的方法或子类可以调用,其他对象无法调用

    默认为public,但initialize方法默认为private

  8. 扩展类

    Ruby允许我们给定义好的类添加方法

    class String    def count_word        ary = self.split(/\s+/)  #==> 用空格分割        return ary.size    endendstr = "David Wang Jordan"p str.count_word  #==>  3
  9. 继承类

    定义类时如果没有指定父类,Ruby默认该类为Object类的子类

    class NewArray < Arrayend

    instance_methods方法——返回该类的实例方法列表

    p "BasicObject", BasicObject.instance_methods#==> [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
  10. 别名

    在重定义已经存在的方法时,可以用别名先把原先的方法保存起来,这样新旧方法都可以调用

    alias  别名   原名   #==>直接使用方法名alias :别名  :原名   #==>使用符号名
  11. 删除方法

    undef  方法名  #==> 直接使用方法名undef :方法名  #==> 使用符号名
  12. 单例类

    给该类的某个对象,定义专属的方法

    str1 = "David"str2 = "Wang"class << str1    def test        p "test"    endendstr1.test   #==> "test"str2.test   #==> 错误
  13. 模块

    • 简介

      类——数据+方法

      模块——只有方法

      模块不能拥有实例

      模块不能被继承

    • 创建/使用模块

      如果想把模块内定义的方法公开给外部使用,需要用module_function方法声明

      模块函数中的self,返回的是使用该模块的类实例。在不同的情况下,self可能会不同,所以不建议在模块函数内部使用self

      module 模块名    模块定义endmodule HelloModule    Version = 1.0                  #==> 定义模块常量    def hello(name)        p "Hello, #{name}."    end    module_function :hello         #==>  指定hello方法为模块函数endp HelloModule::VersionHelloModule.hello("David")include HelloModule                #==>  包含模块p Versionhello("Wang")
  14. Mix-in

    Mix-in就是用include语句,将模块混合到类中

    include?方法——类是否包含某个模块

    ancestors方法——获取继承关系列表

    superclass方法——返回父类

    module Mendclass C    include Mendp C.ancestors   #==> [C, M, Object, Kernel, BasicObject]                #==> Kernel是Ruby内部的一个核心模块,程序运行时所需的共通函数均在此模块内,例如p,raise等

    Ruby不允许多重继承,但通过Mix-in,可以让多个类共享其他功能

  15. 查找方法的规则

    • 本类定义的方法 > include模块中的方法 > 父类的方法

    • 同一个类包含多个模块时,优先使用最后一个包含的模块

    • 相同模块被包含两次以上时,第二次以后的会被省略

    module M1endmodule M2endmodule M3    include M2endclass C    include M1    include M3endp C.ancestors    #==>  [C, M3, M2, M1, Object, Kernel, BasicObject]
  16. extend方法

    • include 通过模块扩展类的功能
    • extend 通过模块扩展对象的功能
    module Testendstr = ""str.extend( Test )
    module IncludeModule    def include_method        p "include_method"    endendmodule ExtendModule    def extend_method        p "extend_method"    endendclass MyClass    extend ExtendModule         #==> 用extend定义类方法    include IncludeModule       #==> 用include定义实例方法endp MyClass.extend_methodp MyClass.new.include_method
0 0
原创粉丝点击