ruby语法-super用法

本文主要介绍ruby中super方法的使用、super方法参数传递、method执行顺序。


下面主要通过实例来说明super方法的使用:

示例1:

#!/usr/bin/env ruby
class A
def a
p 'a 1'
end
def a
p 'a 2'
super
p 'a 2 END'
end
end b = A.new
b.a

示例1输出:

➜  tmp ./test.rb
"a 2"
./test.rb:9:in `a': super: no superclass method `a' for #<A:0x007fac830b0dd8> (NoMethodError)
from ./test.rb:15:in `<main>'

示例1说明:

可以看出,当一个类里面定义了多个相同名称的函数时,后面的会完全覆盖前面的,即前面的方法等于无效。
"a"函数被重新定义后调用了"super"方法报错了。报错信息大致意思是:找不到superclass内的方法"a"。那么是不是使用super方法需要另外一个类呢?

示例2:

#!/usr/bin/env ruby
class B
def a
p 'B a 1'
end
end class A < B
def a
p 'a 1'
end
def a
p 'a 2'
super
p 'a 2 END'
end
end b = A.new
b.a

示例2输出:

➜  tmp ./test.rb
"a 2"
"B a 1"
"a 2 END"

示例2说明:

  • 类A内后面的a函数确实覆盖了前面的。
  • super方法的使用也可以直观的体现出来了,当调用super方法时,类A会自动调用父类B中的"a"方法,然后再回到类A继续执行。

示例2类的调用顺序:

A->B

示例3:

#!/usr/bin/env ruby
module M
def a
p 'M a 1'
end
end class A
include M
def a
p 'a 1'
end
def a
p 'a 2'
super
p 'a 2 END'
end
end b = A.new
b.a

示例3输出:

➜  tmp ./test.rb
"a 2"
"M a 1"
"a 2 END"

示例3说明

module和class的继承有同样的效果。

示例3类的执行顺序

A->M

示例4:

当A类既继承module M又继承类B会怎么样呢?

#!/usr/bin/env ruby
class B
def a
p 'B a 1'
end
end module M
def a
p 'M a 1'
super
p 'M a END'
end
end class A < B
include M
def a
p 'a 1'
end
def a
p 'a 2'
super
p 'a 2 END'
end
end b = A.new
b.a

示例4输出:

➜  tmp ./test.rb
"a 2"
"M a 1"
"B a 1"
"M a END"
"a 2 END"

实例4说明:

如果同时出现了Module和祖先Class,那么程序将先到Module中寻找,然后再到父类中寻找。

示例4类的调用顺序

A->M->B

示例5:

那么当父类里面也使用super调用了M模块会怎么样呢?

#!/usr/bin/env ruby
module M
def a
p 'M a 1'
end
end class B
def a
p 'B a 1'
super
p 'B a END'
end
include M
end class A < B
include M
def a
p 'a 1'
end
def a
p 'a 2'
super
p 'a 2 END'
end
end b = A.new
b.a

示例5输出:

➜  tmp ./test.rb
"a 2"
"B a 1"
"M a 1"
"B a END"
"a 2 END"

示例5说明:

当父类和子类都使用super方法调用了模块M,那么会现执行父类的调用,子类的调用作废。
也就是说如果“老子”和“小子”都想有“XXX”,那么这个“XXX”肯定是归“老子”的了,毕竟“小子”得懂得孝道,不光中国是这样,在日本也是这样的文化吧。

示例5类的调用顺序:

A->B->M

示例6:

以上示例说明了super方法的使用和类的调用顺序,下面介绍下super方法的参数传递,直接上示例:

#!/usr/bin/env ruby
module M
def a(x=5,y=6)
p 'M a 1'
p x
p y
end
end class B
def a(x=3,y=4)
p 'B a 1'
p x
p y
super(x)
p 'B a END'
end
include M
end class A < B
include M
def a
p 'a 1'
end
def a(x=1,y=2)
p 'a 2'
p x
p y
super
p 'a 2 END'
super()
end
end b = A.new
b.a(-1,-2)

示例6输出:

➜  tmp ./test.rb
"a 2"
-1
-2
"B a 1"
-1
-2
"M a 1"
-1
6
"B a END"
"a 2 END"
"B a 1"
3
4
"M a 1"
3
6
"B a END"

示例6说明:

类A使用的super函数,类A的x和y的值全部传递给了B.a;
然后类B使用的super(x),B的x值传递给了模块M;
类A使用的super()函数时,类A的x和y的值都不传递给类;

super方法参数传递:

  • 以裸词super调用祖先/模块方法(callee),则将传递调用者(caller)的全部方法参数;
  • 以super()调用,则不会传递caller的任何参数;
  • 以super(a,b)调用,则将传递部分参数a、b

示例7:

综合的示例,如果能看懂这个示例那么说明你对super方法有了一定的了解:

#!/usr/bin/env ruby
module M
def report( a = 4, b =5)
p "M report begin: a=#{a},b=#{b}"
a = 6
super(a)
p "M report end"
end
end class B
def report(a=11,b=12)
p "B report 1 begin: a=#{a},b=#{b}"
p "B report 1 end"
end
def report(a=13,b=14)
p "B report 2 begin: a=#{a},b=#{b}"
#super
p "B report 2 end"
end
end class C < B
def report( a=8,b=9)
p "C report 1 begin: a=#{a},b=#{b}"
p "C report 1 end"
end
def report( a=7,b=3)
p "C report 2 begin: a =#{a},b=#{b}"
super()
p "C report 2 End"
end
include M
end class D < C
def report( a = 2, b=1)
p "D report 1 begin: a=#{a},b=#{b}"
super(a,b)
p "D report 1 end"
end
include M
def report(a = -2, b=-1)
p "D report 2 begin: a=#{a},b=#{b}"
super
p "D report 2 end"
end
end d = D.new
d.report

示例7输出:

➜  tmp ./test.rb
"D report 2 begin: a=-2,b=-1"
"C report 2 begin: a =-2,b=-1"
"M report begin: a=4,b=5"
"B report 2 begin: a=6,b=14"
"B report 2 end"
"M report end"
"C report 2 End"
"D report 2 end"

总结

  • 同一个class和module中, 如果定义了多个相同的方法,那么后面的方法会完全覆盖前面的方法,前面的方法作废。
  • 使用super函数时方法的调用顺序为:本实例对象的方法-->被继承的module的方法-->父类的方法-->递归的-->...... (当父类和子类同时使用super方法调用了相同的模块,那么父类的调用生效,子类不生效)
  • super的参数传递分为三种:裸词(全部传递)、空(全部不传递)、部分(部分参数传递)

参考文档:

http://www.iteye.com/topic/273704

ruby-super用法的更多相关文章

  1. this和super用法

    1. this能分清混淆,形参名与当前对象的某个成员有相同的名字,需要明确使用this关键字来指明你要使用某个成员,使用方法是“this.成员名”. 一般以this.形参数名=形参名,代表送进来赋值的 ...

  2. JAVA中this和super用法

    参考网上资料和自行理解总结java中this和super中各自用法及其差异 <一>. this的用法 构造方法是创建java对象的重要途径,通过new关键字调用构造器时,构造器返回该类的对 ...

  3. Python中的super()用法

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this,比如:C#),用于传递对象本身,而在调用的时候则不 必显式传递,系统会自动传递. 今天我们介绍的主角是su ...

  4. this和super用法的总结

    在学习this和super关键字时,发现它们有诸多相同点,同时这两个关键字非常常用,现对它们做以下的总结. 一.概况 This: This指代当前对象,this()指代当前对象的其他构造函数 Supe ...

  5. Java中this、super用法

     这节我们主要是区分this 和 super这两个关键字的用法 起初我根本弄不清楚this 和 super这两个关键字的用法,也不明白在代码实例中为什么既用this又用super,下面就是原因: 1. ...

  6. Java—static、this、super用法总结

        通过用static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量.(理解为加了static的就是全局变量)但是,并不是说有了这种便利,你便可 ...

  7. Pythn中的super用法

    在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1: 代码段1: 代码如下: class A: def __init__(self): p ...

  8. 关于Python的super用法研究

    一.问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在python 2.2以前,通常的写法如代码段1: 代码段1: class A:  def __init__(se ...

  9. this和super用法详解

    这几天看到类在继承时会用到this和super,这里就做了一点总结,与各位共同交流,有错误请各位指正~ this this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this ...

  10. Python面向对象中super用法与MRO机制

    1. 引言 最近在研究django rest_framework的源码,老是遇到super,搞得一团蒙,多番查看各路大神博客,总算明白了一点,今天做一点总结. 2. 为什么要用super 1)让代码维 ...

随机推荐

  1. git安装包解压后没有configure

    今天在linux上安装git客户端,解压了tar包后,发现没有configure,无法安装.经查,原来是要先执行autoconf命令,执行后出现configure

  2. centos 下使用vscode 调试egg.js 注意事项

    这两天在centos下,直接用vscode运行egg.js的例子.遇到个问题就是当安装了vscode-egg插件,会遇到一个现象.就是同样的代码,Windows下调试可以顺利进行,但是centos有时 ...

  3. 《笨方法学Python》加分题16

    基础部分 # 载入 sys.argv 模块,以获取脚本运行参数. from sys import argv # 将 argv 解包,并将脚本名赋值给变量 script :将参数赋值给变量 filena ...

  4. [Hbase]Hbase章4 Hbase分区爆了

    又搞事了,发生了啥事呢:生产分区数暴了,What? 目前的情况: 前提:单Region Server分区上限设置为1000: 目前A表的数据量半年达到25E,20G一分区,达到了900多个分区,这是要 ...

  5. Maven 的这 7 个问题你思考过没有?

    在如今的互联网项目开发当中,特别是Java领域,可以说Maven随处可见.Maven的仓库管理.依赖管理.继承和聚合等特性为项目的构建提供了一整套完善的解决方案,可以说如果你搞不懂Maven,那么一个 ...

  6. shell脚本编写某一文件夹内拷贝某一段文件(有则跳过没有则拷贝)

    必须是同一台服务器下,或者挂载目录,不同服务器下没办法查询目录中是否有该文件 如果不在同一服务器下,可以把要查询的那个服务器的文件夹设置共享挂在到当前服务器 或者可以把脚本写到要拷贝的服务器上,那么s ...

  7. final,static,abstract

    一.final 1.可以修饰属性,表示常量,其值在运行期间不允许改变.常量必须赋初始值,初始值可以在声明出,构造方法的任意一个地方赋 优点:增强程序的可读性,可维护性 2.可以修饰方法,表示该方法不能 ...

  8. windows 多网卡路由设置

    1.问题 windows操作系统,双网卡连接内外网,配置路由使内网请求走内网网卡,外网请求走外网网卡 2.网络参数 内网网卡 IP:172.22.25.152 mask: 255.255.255.0 ...

  9. 理解存储引擎MyISAM与InnoDB

    1.MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.不 ...

  10. freeType移植总结①——使用keil编译freeType2库

    在各个技术博客搜索相关资料后,终于将freeType的源码用keil工程编译通过,这里记录一下步骤和遇到的问题. 因为网上的资料都是旧版本freeType的工程,这里博主使用的是freeType2.9 ...