【问题标题】:Ruby Class Relationships: How do I use methods and objects from another class?Ruby 类关系:如何使用另一个类的方法和对象?
【发布时间】:2014-12-30 13:41:18
【问题描述】:

感谢您查看我的问题! :)

我对 Ruby 编程相当陌生,我无法理解如何在我的代码中实现类,以及如何让它们相互继承方法和变量。

我有一个灯泡类,它看起来像这样:

class LightBulb
  def initialize( watts, on )
    @watts = watts
    @on = on
  end

  # accessor methods
  def watts
    @watts
  end

  def on
    @on
  end

  # other methods
  def turnon
    @on = true
  end

  def turnoff
    @on = false
  end

  def to_s
    "#{@watts}-#{@on}"
  end
end

以及与该类一起工作的驱动程序:

# a lit, 30-watt bulb

b = LightBulb.new( 30, false )
b.turnon( )
Bulb    

# a 50-watt bulb

fiftyWatt = LightBulb.new( 50, false )
fiftyWatt.turnoff( )

...我正在尝试创建一个具有灯泡的类 Lamp 并在不同时间使用它。我知道在继承树图上,它们应该彼此相邻(即 LightBulb--Lamp,而不是 LightBulb

Lamp ( string make, string model, double cost, int watts )
-- accessors
string make( ) 
string model( ) 
-- methods
void turnon( ) # turn on the bulb
void turnoff( ) # turn off the bulb
--class members
string make
string model
double cost
LightBulb bulb

如何在 Lamp 类中使用 LightBulb 类的 turnon() 和 turnoff() 方法以及灯泡对象?

到目前为止,这是我对 Lamp 的了解,但我确信其中大部分是不正确的:

class Lamp
    attr_accessor :watts
    def initialize(make, model, cost, watts)
        @make = make
        @model = model
        @cost = cost
        @watts = LightBulb.new(:watts)
    end

    def make
        @make
    end

    def model
        @model
    end

    def cost
        @cost
    end
end

【问题讨论】:

  • 看起来你走在正确的轨道上。在不小心将watts 之类的参数作为符号传递时要小心,您的new(:watts) 应该是new(watts)
  • 参考您的对象规范:在没有显式返回 nil 的情况下,Ruby 中没有 void 方法之类的东西。仅供参考。

标签: ruby class inheritance methods


【解决方案1】:

这里绝对不需要继承。您正在组合这些对象,一盏灯有一个灯泡。您已经很接近了,您真正需要做的就是调用您缺少的 LightBulb 上的方法:

class Lamp

  def initialize(make, model, cost, watts)
    @make = make
    @model = model
    @cost = cost
    @bulb = LightBulb.new(watts, false)
  end

  # ... 

  def turnon
    @bulb.turnon
  end

  def turnoff
    @bulb.turnoff
  end

end

所以我将@watts 更改为@bulb,并删除了:watts 符号,因为您确实需要传递传入的watts 的值。如果您有兴趣,here is some more information on symbols

【讨论】:

  • 非常感谢尼克,我很困惑如何在我的初始化方法中引用其他类,但你完全清除了它!而且我对符号也很陌生,所以再次感谢您解释我应该如何传递变量。 :)
【解决方案2】:

在面向对象的术语中,这可以通过委派这些方法来完成:

class Lamp
  def turnon
    @lightbulb.turnof
  end

  def turnoff
    @lightbulb.turnoff
  end
end

这些传递方法在 Ruby 代码中相当常见,您需要将一个对象包装在另一个对象中。

如果您喜欢冒险,还有 Forwardable 模块。

从面向对象设计的角度来看,我会更关心这里的责任链。例如,虽然灯泡具有关闭/打开状态,但灯本身充当其“控制器”。没错,这不是继承,而是封装。

【讨论】:

  • 感谢您的帮助,我想我现在理解了这些概念;而且我对稍微接近正确答案感到更有信心。 :)
猜你喜欢
  • 2011-11-28
  • 2020-12-31
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多