Ruby 类(超级)

Ruby Classes (Super)

我这周刚开始 classes 在 Bloc。我已经用 Ruby 练习了大约 3 个月,但我终于被卡住了。希望能得到一些帮助。

我卡住的部分属于 Super

以下是纯格式规范:

这是我想要达到的 RSpec 规格:

describe President do
  describe "initialization" do
    it "takes a name and age, and delegates citizenship to the class default" do
      prez = President.new("George Washington", 283)
      expect( prez.name ).to eq("George Washington")
      expect( prez.age ).to eq(283)
    end
  end

  describe "children" do
    it "is the parent of FrancePresident and UnitedStatesPresident" do
      expect( FrancePresident.superclass ).to eq(President)
      expect( UnitedStatesPresident.superclass ).to eq(President)
    end
  end
end

describe FrancePresident do
  describe "catchphrase" do
    it "sounds just right" do
      expect( FrancePresident.citizenship ).to eq("La France")
      sarcozy = FrancePresident.new("Nicolas Sarkozy", 59)
      expect( sarcozy.citizenship ).to eq("La France, bien sur")
      expect( sarcozy.age ).to eq("59, bien sur")
      expect( sarcozy.name ).to eq("Nicolas Sarkozy, bien sur")
    end
  end
end

这是我目前的代码:

class President
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age 
  end
end

class FrancePresident < President
  def self.citizenship
    "La France"
  end
end

class UnitedStatesPresident < President
  def self.citizenship
    "The United States of America"
  end
end

总而言之,我一直在尝试让 citizenship class 方法起作用。从说明来看,他们似乎希望我在 President 中定义一个 citizenship class 方法。但我看不出这是如何工作并符合规范的,因为据我所知,你不能为每个 child 单独设置公民身份。

所以基本上我停留在第三和第四个目标上。如果你有时间,请就此回复我。

首先你要找的不是class方法,应该是实例方法。 这是我理解的重构代码:

class President
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def citizenship
    self.class.citizenship
  end

end

class FrancePresident < President
  END_STRING = ", bien sur"

  def self.citizenship
    "La France"
  end

  def age
    "#{@age}#{END_STRING}"
  end

  def name
    "#{@name}#{END_STRING}"
  end
  def citizenship
    "#{self.class.citizenship}#{END_STRING}"
  end
end

class UnitedStatesPresident < President
  def self.citizenship
    "The United States of America"
  end
end



aa = UnitedStatesPresident.new("Roosevelt", 35)
puts aa.citizenship
puts aa.name
puts aa.age
ff = FrancePresident.new("France", 35)
puts ff.citizenship
puts ff.name
puts ff.age

在您的规范中,您期望有两种类型的 citizenship 响应。一个有标语,一个没有。所以你必须有两种不同的方法。一个 class 方法,一个实例方法。它应该沿着这些方向:

class FrancePresident < President
  def self.citizenship
    "La France"
  end

  # instance method which adds the catchphrase
  def citizenship
    append_catchphrase(self.class.citizenship)
  end

  # here's your super
  def age
    append_catchphrase(super)
  end

  def catchphrase
    'bien sur'
  end

  private

  def append_catchphrase(val)
    [val, catchphrase].join(', ')
  end
end

你已经很接近了,除了 class 方法

之外,你只需要在子 classes 中定义实例方法
class FrancePresident < President
  def self.citizenship
    "La France"
  end

  def citizenship
    "La France, bien sur"
  end
end

class UnitedStatesPresident < President
  def self.citizenship
    "The United States of America"
  end

  def citizenship
    "The United States of America"
  end
end

首先我认为citizenship method应该是instance method,你可以在你的President class中定义,在child classes中覆盖它。 对于您的最后一个 objective,这里有一个示例:

class FrancePresident < President
  # citizenship method
  def name
    super + ", bien sur"
  end 
  def age
   super + ", bien sur"
  end
end