Ruby class relationships: how to use methods and objects from another class?

Thanks for looking at my question! :)

I am new to Ruby programming and I am having a hard time figuring out how to implement classes in my code and inherit their methods and variables from each other.

I have a LightBulb class that looks like this:

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

      

and the driver program that works with the class:

# a lit, 30-watt bulb

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

# a 50-watt bulb

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

      

... and I'm trying to create a Lamp class that has a LightBulb and uses it at different times. I know that in the inheritance tree diagram they should be next to each other (e.g. LightBulb - Lamp, instead of LightBulb <- Lamp), so I don't know if <inheritance should be used. Here is the basic structure I need for the Lamp class:

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

      

How can I use the turnon () and turnoff () methods from the LightBulb class, and the bulb object in the Lamp class?

Here's what I have for the lamp now, but I'm sure most of them are wrong:

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

      

+3


source to share


2 answers


You definitely don't need inheritance here. You compose these objects, the lamp has a LightBulb. You are close and all you really need to do is call the methods on LightBulb that you are missing:

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

      



So I changed @watts

to @bulb

and dropped the character :watts

since you really need to pass the value watts

that was passed in. If you're curious, here's some more information on symbols .

+3


source


In object oriented terms, this can be done by delegating these methods:

class Lamp
  def turnon
    @lightbulb.turnof
  end

  def turnoff
    @lightbulb.turnoff
  end
end

      

These pass-through methods are quite common in Ruby code where you need to wrap one object inside another.



There is also a Forwardable module if you are feeling more adventurous.

From an object oriented design perspective, I'm more concerned about the chain of responsibility. For example, although the lamp has an on / off state, the lamp itself acts as a "controller". You are correct that this is not a case of inheritance, but instead of encapsulation.

+2


source







All Articles