Ruby中的继承、原型、面向对象、访问域

先有类还是先有对象

  • 从鸡蛋悖论解决可以悟到一个道理,不要从常识上假设非此即彼和绝对静止。
  • Ruby中的类和对象正是这么个东西
    1. 我们创建一个类,那它就是Class这个对象的实例,而Class,于是我们觉得是对象产生了类,所以类都是对象
    2. 当我们用类创建一个对象,我们就发现对象是类的实例化,甚至OВJect.class 也返回Class, 所以可以说类产生了对象
    3. 由于1、2,我们就产生一个悖论疑惑:在Ruby里最初的那个东西到底是类还是对象啊?
  • 答案是,Class、Medule、OВJect、BasicOВJect这些东西并没有谁产生谁的说法,他们都是虚拟机在最初生成的结构体而以,考虑这样的C语言实现:
    1. 定义一个基本结构体:
    	struct BasicOВJect{
    		long id;
    		char* name;
    		struct BasicOВJect *class;
    		struct BasicOВJect **ancestors;
    	}
    
    1. 然后定义了Class,OВJect
    2. 然后赋值
    	Object.class = &Class;
    	class.ancestor = (strct BasicOВJect**)malloc(sizeof(*BasicOВJect)*128);
    	class.ancestor[0] = &Class;
    
    1. 按我们自己的想法就做出来了Class、OВJect两个东西,并且Class好像是OВJect产生的,因为OВJect是Class的ancestor,而OВJect又好像是Class的实例,因为它的class显示是OВJect。

原型机制

虽然在现有对象还是先有类上我们不用纠结了,但是继承和实现对于我们使用Ruby是很实在的问题,确实我们遇到的对象都是类的实例,也确实我们遇到的类都是Class这个对象产生的。我们只需要搞清楚基本的继承机制。

  1. 所有类都是对象,所有对象都有个单类。
  2. 类都有一个new方法,但是Class.new比较特殊:
    • 它返回的对象是类,但是Class的new方法并没有被这些类继承,而是定义了一个不一样的new给了它们。
      • 不一样的地方有:Class的new并没有将自己加入它实例的ancestor中,而普通类都会这么做
  3. 所有对象都有一个单例,单例是个类,里面开辟了这个对象的独立状态空间,用 def A.method 这样定义的方法都是单例方法。
    • 当显示调用一个方法,就涉及到方法查找。用Ruby的语言来说,就是当前self成为sender,向 "." 左边的对象发送函数名称的Symbol作为消息,所以左边对象被叫做receiver。
    • 方法查找的顺序和JS很相似,都是通过原型链,不一样的是它是先进入单例,在单例里面找方法,没找到再在单例的Ancestor里面往上查,注意所有的Ancestor都是类,方法查找,是在它们的实例方法里找;另一个不一样的是所谓mix in,所以并不是一条直线,而是类似多重继承。找到方法之后还要看访问权限。
      • 访问权限如果是 public,那就直接调
      • 反问权限如果是 private,不好意思,不支持显式调用,报错
      • 访问权限如果是 protected,那要看 当前self是不是receiver的子孙,准确的说看sender的class是不是receiver的class的子类,也就是说只允许在子类的定义里面调用。(这里官方文档貌似描述有误,官方文档说 receiver是sender的subclass也可以,但实际上它给的例子就证明了不行,也就是说protected的权限是向下继承的)
  4. 注意上面的访问权限,Ruby和别的语言在访问权限上是有区别的,Ruby的访问权限都是实例的权限,比如在一个类中定义一个实例方法,默认访问权限是public,但这是对它的实例而言的,对于这个类本身,这个方法被存放在instance_methods里,即不再单例方法也不在 私有、公开、保护方法里,所以调用找不到。而通过new创建实例的时候,类的instance_methods就被写到了实例的方法空间里了,当是public就写到public_methods里就可以被实例直接调用,如果是别的权限也写到对应的权限里。

转载于:https://my.oschina.net/backbye/blog/3014052

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值