关于self 类的应用

class A
  C = 1
end
class B < A
  class << self
    def test1
      puts C
    end
  end
  def self.test2
    puts C
  end
  def test3
    puts C
  end
end


=begin
主要来看下一下几种输出,看他们的结果都有什么样的?

 p B.test1
 p B.test2
 我们来执行下这段代码输出就发现,会报错: in `test1': uninitialized constant Class::C (NameError)
 为什么会报这个错误的?
 我们会有疑问?
 为什么在test2或者test3中可以直接使用C,在test1中就不能使用那?

 p B.test2
 p B.new.test3
 p B.test3
 我们来执行下这段代码输出的时候就发现,会报错: undefined method `test3' for B:Class (NoMethodError)
 我们又会产生疑问了?
 为什么test2 和 test3的调用方法不一样那?

 先Hold的问题,听下面的一些讲解,你就会明白了。这块内容主要涉及到以下几点的内容

 a. 关于类常量的作用域,以及使用范围
    以大写字母打头的标识符是常量,对常量进行二次赋值解释器会提示警告,
    而引用未被赋值的常量实抛出 NameError 异常。
    在类、模块外部定义的常量属于 Object,可以使用“::常量名”
    引用属于 Object 的常量,以“模块名/类名::常量名”的形式引用外部的常量
    类内直接使用,继承类的类方法内直接使用类常量,继承类的类实例方法必须使用 类/模块::常量

    下面就要说下什么是类方法?什么又是实例方法?

 b. 关于类方法,形如一下格式:
     def 类名.方法
        ***********
     end
    这个表示是属于类专用的方法,不属于类对象的方法, 使用:类名.方法
    class B < A
       def self.test2
           puts C
       end
    end
   同价于:
   class B < A
       def B.test2
           puts C
       end
    end
    调用:
         B.test2

 c. 实例方法
    class B < A
       def test3
           puts C
       end
    end
    这个是我们习惯性的写法,这个是属于类实例方法,属于类对象的专属方法,类不能直接使用。
    调用用到时候必须先实例化,new一个对象,然后调用。
    如: B.new.test3

 d. 关于类对象追加方法用法
    给特定的类对象追加方法或者属性,这些方法和属性是直接封装到一个类中,直接追加到对象中。
    这个类没有特定的名字,所以不能像普通的类一样使用。
    格式如下:
      Class << obj
      end
    本例中使用如下:
    class B < A
        class << self
          def test1
            puts C
          end
       end
    end
   这个里面我们使用到了<< 和self,   << 是追加的意思,self的含义:当前对象,或者是默认对象
   这个虚拟类(元类 metaclass)的self指的的是什么那?
    self这个在虚拟类中指的默认对象是:#<Class:B>
    self这个在虚拟类中的test1方法中指的默认对象是:B,如同在class B中的self

   这个是用到了ruby的单件类或叫metaclass 也有叫singletonclass。
   这个类的执行环境就相当于不在Class B中了,虽然写在这个位置。从self可以看出他们的执行对象是不同的。

 e. 关于继承
    这个就不多讲了,A<B 就是A继承了B ,A 是B的子类,可以使用A的所有资源,A可以重写父类方法。如同java的继承。
   Ruby是单继承的,但是也能实现多继承的可以实现的一切。。

  使用Model模块,在类中include 模块 就能达到多继承的效果了。

现在我们再来看代码:

下面我们来分析下test1 test2 test3 三个方法:

我们主要来看下他的执行环境吧,即class执行的一个有效范围吧,即 self对象指的是什么东西?
 test1: 是B的单例类的方法。 这个特殊类的执行环境是在B类外的。
 test2: 是类方法,B继承了A,就继承了C,可以在类的方法(类方法和类实例方法)中使用。执行环境是Class B中
 test3: 是B的类对象方法,执行环境是类B中:Class B ---> end

所以在test1中使用常量,就相当于在类外使用类常量了。
   使用方式如下:A::C 或者B::C 或者self::C
为什么可以使用self::C那?
 因为test1方法中的self 指的是:B 等价于 使用B::C,B继承A,写成A::C也是ok的
=end


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值