【问题标题】:Is it possible to do polymorphism by doing overloading? [duplicate]是否可以通过重载来实现多态性? [复制]
【发布时间】:2016-10-06 09:13:43
【问题描述】:

我正在尝试执行以下操作:

class SUM
  def make_sum (number)
    return number+number
  end 

  def make_sum (number_a, number_b)
    return number_a+number_b
  end 
end

operation = SUM.new
operation.make_sum(5)    # returns 10
operation.make_sum(2, 3) # returns 5

一个输入的make_sum方法由一个有两个输入的重新定义。

【问题讨论】:

  • 我同意强尼的观点。虽然就问题的表述方式而言并不是严格意义上的重复,但它触及了问题的本质:“参数的数量”、“参数的类型”等实际上通常被称为“重载”而不是“多态性”。多态性有点不同,多次调度也与“输入数量”不同。 'why doesn't ruby​​(..)' 问题表明不支持重载以及为什么,这也总结了这个问题。
  • 但是,正如 Keith 和 marcus 在他们的回答中所展示的,即使“重载”是不可能的,您也可以使用 *args 技巧来模拟它 - 将参数作为数组,检查该数组的长度,然后根据该长度做一些不同的事情。但这既不是多态性,也不是重载。这只是没有面向对象名称的手动编码(因为它与 OO 无关 :))。一个通用名称就是splat argssplat operatorSee here for some examples
  • 不,你不能在 ruby​​ 中定义两个同名但参数不同的方法。最后一个“赢了”,第一个方法定义根本不存在了。

标签: ruby polymorphism


【解决方案1】:

如果添加是您所追求的,您可以更简单地执行以下操作:

def add(*numbers)
  numbers.inject(&:+)
end

add(1) # => 1
add(1, 3, 5) # => 9

如果您正在寻找更通用的解决方案来解决如何根据参数数量提供行为的问题,那么您可以在签名中使用*args,然后基于args.size 进行分支:

def foo(*args)
   case args.size
     when 1
        # do something
     when 2
        # do something else
     when (3..5)
        # do another thing
   end
 end

【讨论】:

    【解决方案2】:

    我对此的反应与@keith-bennett 相同。但我不知道这和他的回答一样简单。这是我的解决方案:

    class Foo
      def self.add(*args)
          r = 0
          if args.length > 1
              args.each { |a| r += a.to_i }
          else
              r += (args[0].to_i + args[0].to_i)
          end
          return r
      end
    end
    
    f = Foo
    puts f.add(1, 2)
    # => 3
    puts f.add(1)
    # => 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      相关资源
      最近更新 更多