新手问题 Ruby 中有要求强制实现的虚函数吗?

michael · October 23, 2015 · Last by michael replied at March 24, 2016 · 3167 hits

如果没有,如何实现虚函数?有无修饰符号或说明符号提示?

定义个一个空函数,然后在里面抛异常

class Person
  def name
    raise "请实现该接口"
  end
end

class Customer < Person
end

c = Customer.new
c.name #异常了 请实现该接口

def c.name
  "实现完了"
end

c.name # 实现完了

你可以理解为 Ruby 所有的方法 都是虚函数,所有的方法都可以被重写

#2 楼 @ery can be overrided != MUST be overrided 啊,我问的正式这一点。我猜动态语言中都没这种用法,无论是 Python, JavaScript 还是 Ruby, 因为没有编译时。我不太懂 OO,今天想用 virtual functioin,结果没有,特来提问。

没有。

#3 楼 @michael 动态语言没有,静态语言编译器可以检查。动态语言如果这个方法没有被调用,那一直不会触发那个异常。

@rei @jimrokliu 那怎么使用继承机制完成这种目的?目前我是直接子类继承+override,父类 call overrided function

#6 楼 @michael

class P
  def aa
     puts "aa"
  end
  def call_aa
     self.aa
  end
end

class S
   def aa
     puts "ss aa"
   end
end

S.new.call_aa

是这样吗?

#7 楼 @jimrokliu 对,现在这样实现的。但这样必须写明白,P.aa() 是假的,S.aa() 才是真的,如果你来写继承会这么写吗?

class P
  def call_hello
     self.hello
  end
end

class S < P
   def hello
     puts "Hello World!!!"
   end
end

S.new.call_hello # Hello Word!!!
P.new.call_hello # 抛异常 undefined method `hello'

Ruby 实现“OO 多态”的方式和静态语言不同, Ruby 没有接口和虚函数的概念, Ruby 采用的方式是"duck type" 。 所以不需要在基类中定义“纯虚函数”。

因为 Ruby 没有编译过程,所以可以通过运行期的异常,来代替/模拟,静态语言中的编译报错。 比如,可以用 ruby 的“undefined method”的异常,来代替/模拟,静态语言的“MUST be overrided”的编译报错。

#9 楼 @ery "不需要在基类中定义“纯虚函数”", 大概会忘记子类应该实现这个东西,只能交给测试覆盖。

#11 楼 @michael ruby 的动态性,失去了编译器检查的优点。只能靠测试驱动来弥补这个弱势,不过因为没有类型检查,也获得了其它好处,例如 Duck typing。

如果用 mixin 的方式,倒是可以提示你要实现什么

module Person
  def self.included x
    ms = x.instance_methods(false)
    [:xx, :yy, :zz].each do |xn|
      raise "请实现 #{xn} 接口" unless ms.include?(xn)
    end
  end
end

class Customer
  def xx;end
  def yy;end
  def zz;end
  include Person
end

c = Customer.new
c.xx
c.yy
c.zz

You need to Sign in before reply, if you don't have an account, please Sign up first.