Ruby类继承以及如何避免调用super两次

时间:2016-02-24 02:53:55

标签: ruby inheritance super

我正在构建一个国际象棋游戏。我正在尝试使用Combining Enclosing Square生成每个棋子,虽然我可以在每个类中手动输入它,但我想通过继承来实现。我无法避免每个子类调用super两次。我很感激任何帮助。

代码:

class Piece
  attr_accessor :color, :piece

  def initialize(color)
    @color = color
    @piece = "#{@piece}\u20DE"
  end
end

class King < Piece
  def initialize(color)
    super
    @piece = "♔" if @color == "white"
    @piece = "♚" if @color == "black"
    super
  end
end

2 个答案:

答案 0 :(得分:2)

我定义了一个二传手。反正它更干净。

 class Piece
  attr_accessor :color, :piece

  def initialize(color)
    @color = color
    @piece = "#{@piece}\u20DE"
  end
  def piece=(piece)
    @piece = "#{piece}\u20DE"
  end
end

class King < Piece
  def initialize(color)
    super
    self.piece = "♔" if @color == "white"
    self.piece = "♚" if @color == "black"
  end
end

k =  King.new('white')
puts k.piece
w = King.new('black')
puts w.piece

结果:

$ ruby chess.rb
♔⃞
♚⃞

还有两件事:

  • 拥有一个带有@piece属性的类是令人困惑的。
  • 如果您不希望修改@piece,请使用attr_reader。 (我会说典当促销是一件新作品,而不是改成女王的典当)。
  • 跳过setter,只需定义to_s,这会增加一些语义值。

答案 1 :(得分:2)

就个人而言,我会完全将这个逻辑移出构造函数:

class Piece
  attr_reader :color

  def initialize(color)
    @color = color
  end

  def piece
    @piece ||= "#{base_piece}\u20DE"
  end
  alias :to_s :piece

  private
  def base_piece
    self.class.const_get(color.upcase)
  end
end

class King < Piece
  WHITE = "♔"
  BLACK = "♚"
end

puts King.new(:black), King.new(:white)
# => ♚⃞
#    ♔⃞