形状继承示例和“Ruby 方式”

发布于 2024-07-25 21:04:27 字数 570 浏览 2 评论 0原文

在我从十年的 C++ 过渡到 Ruby 的过程中,我发现自己在重新思考如何完成最简单的事情。 鉴于下面的经典形状推导示例,我想知道这是否是“Ruby Way”。 虽然我相信下面的代码本质上没有任何问题,但我感觉我没有充分利用 Ruby 的全部功能。

class Shape
  def initialize
  end
end

class TwoD < Shape
  def initialize
    super()
  end

  def area
     return 0.0
  end
end

class Square < TwoD
  def initialize( side )
    super()
    @side = side
  end

  def area
    return @side * @side
  end
end

def shapeArea( twod )
  puts twod.area
end

square = Square.new( 2 )

shapeArea( square ) # => 4

这是实施“Ruby Way”吗? 如果没有,您将如何实施?

In my quest to transition from a decade of C++ to Ruby, I find myself second guessing how to accomplish the simplest things. Given the classic shape derivation example below, I'm wondering if this is "The Ruby Way". While I believe there's nothing inherently wrong with the code below, I'm left feeling that I'm not harnessing the full power of Ruby.

class Shape
  def initialize
  end
end

class TwoD < Shape
  def initialize
    super()
  end

  def area
     return 0.0
  end
end

class Square < TwoD
  def initialize( side )
    super()
    @side = side
  end

  def area
    return @side * @side
  end
end

def shapeArea( twod )
  puts twod.area
end

square = Square.new( 2 )

shapeArea( square ) # => 4

Is this implemented "The Ruby Way"? If not, how would you have implemented this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

记忆消瘦 2024-08-01 21:04:27

Ruby 的美妙之处在于,您不必仅仅为了提供已实现方法的契约而使用继承。 相反,您可以这样做:

class Square
  def initialize(side)
    @side = side
  end

  def area
    @side * @side
  end
end

class Circle
  def initialize(radius)
    @radius = radius
  end

  def area
    @radius * @radius * 3.14159
  end
end

shapeArea(Square.new(2))
shapeArea(Circle.new(5))

这是一个称为鸭子类型的功能。 只要twod有一个area方法(用Ruby的说法,我们会说twod响应area),你就可以开始了。

The beautiful thing about Ruby is you don't have to use inheritance just to provide a contract of implemented methods. Instead, you could have done this:

class Square
  def initialize(side)
    @side = side
  end

  def area
    @side * @side
  end
end

class Circle
  def initialize(radius)
    @radius = radius
  end

  def area
    @radius * @radius * 3.14159
  end
end

shapeArea(Square.new(2))
shapeArea(Circle.new(5))

This is a feature known as duck typing. So long as twod has an area method (in Ruby parlance we'd say twod responds to area), you're good to go.

在梵高的星空下 2024-08-01 21:04:27

第一个答案是“Ruby 方式”,但如果您感受到从 C++(高度类型)到 ruby​​(鸭子类型)的变化,您可以让它感觉更像家:

class TwoD < Shape
  ...
  def area
    # make this truly look pure-virtual
    raise NoMethodError, "Pure virtual function called"
  end
end

当然,您正在过渡到 ruby​​,所以你也可以避免重复自己:

class Module
  def pure_virtual(*syms)
    syms.each do |s|
      define_method(s) { raise NoMethodError, "Pure virtual function called: #{s}" }
    end
  end
end

class TwoD < Shape
  pure_virtual :area
  ...
end

The first answer is "the ruby way", but if you're feeling the change from C++ (highly-typed) to ruby (duck-typing) you can make it feel more like home:

class TwoD < Shape
  ...
  def area
    # make this truly look pure-virtual
    raise NoMethodError, "Pure virtual function called"
  end
end

Of course you're transitioning to ruby so you could also avoid repeating yourself:

class Module
  def pure_virtual(*syms)
    syms.each do |s|
      define_method(s) { raise NoMethodError, "Pure virtual function called: #{s}" }
    end
  end
end

class TwoD < Shape
  pure_virtual :area
  ...
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文