# (Wall) require 'minitest/autorun' describe Wall do let(:wall) { Wall.new } it 'should state its dimensions' do wall.dimensions.must_equal 'I am 30ft. long and 20ft. wide!' end it 'should be made from brick' do wall.made_from.must_equal 'I am made from brick!' end end
class Wall def dimensions 'I am 30ft. long and 20ft. wide!' end def made_from 'I am made from brick!' end end
Wall
). # (BrickWall) describe BrickWall do let(:brick_wall) { BrickWall.new } it 'should state its dimensions' do brick_wall.dimensions.must_equal 'I am 30ft. long and 20ft. wide!' end it 'should be made from brick' do brick_wall.made_from.must_equal 'I am made from brick!' end end # (ConcreteWall) describe ConcreteWall do let(:concrete_wall) { ConcreteWall.new } it 'should state its dimensions' do concrete_wall.dimensions.must_equal 'I am 30ft. long and 20ft. wide!' end it 'should be made from concrete' do concrete_wall.made_from.must_equal 'I am made from concrete!' end end # (WoodWall) describe WoodWall do let(:wood_wall) { WoodWall.new } it 'should state its dimensions' do wood_wall.dimensions.must_equal 'I am 10ft. long and 20ft. wide!' end it 'should be made from wood' do wood_wall.made_from.must_equal 'I am made from wood!' end end
BrickWall
, ConcreteWall
and WoodWall
. It looks like a nice idea, but we will have to hardcode each instance method. What if a house needs a dozen different types of walls?Wall
class (our skeleton class) and its subclasses: BrickWall
, ConcreteWall
and WoodWall
.#dimensions
and #made_from
methods that return slightly different rows. With this in mind, let's implement our wall class and its subclasses. class Wall def dimensions "I am #{length}ft. long and #{width}ft. wide!" end def made_from "I am made from #{material}!" end private def length 30 end end class BrickWall < Wall private def width 20 end def material 'brick' end end class ConcreteWall < Wall private def width 20 end def material 'concrete' end end class WoodWall < Wall private def length 10 end def width 20 end def material 'wood' end end
Wall
class, we define the private method #length
because we see that BrickWall
and ConcreteWall
have the same length. As for the WoodWall
class, we simply redefined #length
to return the value 10
. This is an example hook method. class Wall ... private def length raise NotImplementedError, 'Sorry, you have to override length' end end class BrickWall < Wall private ... def length 30 end end
#length
class #length
method is made as a stub for #lenght
in BrickWall
, a particular class. In essence, the hook method informs all concrete classes that the method should be overridden. If the base implementation is not defined, then subclasses are required to implement hook methods.Source: https://habr.com/ru/post/188046/
All Articles