[Ruby] Class
Collection Class
Managing our game library is getting a little difficult with all of these game instances floating around. Let's create a newLibrary class which will manage a collection of Game objects. Create a Library class whose initializer stores a gamesarray. Ensure games is publicly accessible.
class Library attr_accessor :games def initialize(games) @games = games end end
Encapsulation
We got a little ahead of ourselves and added a has_game? method to Library that takes in the name of a game. Then, we realized that it doesn't compare year or system! Rather than passing in a game name to the has_game? method, pass in an instance of a game, and check for equality with the entire game object using the declared == method on Game.
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] @created_at = Time.now end def ==(game) name == game.name && system == game.system && year == game.year end end
class Library attr_accessor :games def initialize(games) self.games = games end def has_game?(search_name) for game in games return true if game.name == search_name end false end end
Answer:
class Library attr_accessor :games def initialize(games) self.games = games end def has_game?(search_name) for game in games return true if game.==(game) end false end
end
Instance Method
We can initialize our Library with an array of games, but the only way to add games from outside the class is to use thegames accessor method and alter the array. This is breaking encapsulation, so let's create a new method in Librarycalled add_game which takes in a game and adds it to the games array.
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] @created_at = Time.now end end
class Library attr_accessor :games def initialize(games) self.games = games end def has_game?(search_game) for game in games return true if game == search_game end false end end
Answer:
class Library
attr_accessor :games
def initialize(games)
self.games = games
end
def add_game(game)
self.games << game
end
def has_game?(search_game)
for game in games
return true if game == search_game
end
false
end
end
Private Method
Things are looking good! We're able to use our Library class to store our games now. Whenever we call add_game, let's call a new private method called log which will call puts with some information about the game that was added. Yourlog method should take in a string to be displayed.
class Library attr_accessor :games def initialize(games) self.games = games end def has_game?(search_game) for game in games return true if game == search_game end false end def add_game(game) games << game log("Add game info: #{game}") end private def log(info) puts info end end
Inheritance
Our game class is getting a little overloaded trying to handle both console games and our old arcade console units (which are really heavy, by the way). Let's create two subclasses of Game: one for ArcadeGame and another for ConsoleGame.
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] @created_at = Time.now end end
Answer:
class ArcadeGame < Game end class ConsoleGame < Game end
Inheritance II
For our ArcadeGame class, we'll also want to track the weight of these giant cabinets taking up all of our available space. Luckily we thought ahead: we already take in an options parameter that we can stick weight into! Override theinitialize method for ArcadeGame to take in the same parameters as its parent class, call super, and then setweight.
ddr = ArcadeGame.new("Dance Dance Revolution", year: 1998, weight: 800, system: 'Bemani System 573 Analog')
Answer:
class ArcadeGame < Game attr_accessor :weight def initialize(game_name, options={}) super self.weight = options[:weight] end end class ConsoleGame < Game end
Inheritance III
Whenever we output a game right now it'll show up using the to_s method from Object, the parent object of Game. A basic to_s implementation is completed below on Game. Override this for ConsoleGame to also show the system the game is on.
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] self.created_at = Time.now end def to_s self.name end end
Answer:
CONSOLE_GAME.RB class ConsoleGame < Game def to_s "#{self.name} - #{self.system}" end end
Refactoring
Our to_s method will come in very handy. Whenever we need to output a game, rather than calling a method on the game, we can just output the game object and Ruby will call to_s on it automatically. Refactor both classes below. Change the description method of Game to use the to_s method implicitly. Then remove any duplicated code inConsoleGame. Note: you'll need to use self inside a class to reference the entire object.
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] @created_at = Time.now end def to_s self.name end def description "#{self.name} was released in #{self.year}." end end class ConsoleGame < Game def to_s "#{self.name} - #{self.system}" end def description "#{self.name} - #{self.system} was released in #{self.year}." end end
Answer:
class Game attr_accessor :name, :year, :system attr_reader :created_at def initialize(name, options={}) self.name = name self.year = options[:year] self.system = options[:system] @created_at = Time.now end def to_s self.name end def description "#{self} was released in #{self.year}." end end class ConsoleGame < Game def to_s "#{self.name} - #{self.system}" end end

浙公网安备 33010602011771号