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

Ruby class inheritance and how to avoid calling super twice

我正在构建一个国际象棋游戏。我正在尝试用组合封闭方块生成每个棋子,虽然我可以手动将其输入每个 class,但我想通过继承来完成。我无法避免每个子 class 调用 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

我会定义一个 setter。反正更干净了。

 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
♔⃞
♚⃞

还有两件事:

  • class 带有属性@piece 的 Piece 令人困惑。
  • 如果您不希望修改@piece,请使用attr_reader。 (我会说典当晋升是新棋子,而不是典当变皇后)。
  • 跳过 setter,只需定义 to_s,这会增加一些语义值。

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

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)
# => ♚⃞
#    ♔⃞