1

我有一堂课是这样开始的:

class Hedgehogs
  attr_accessor :name, :age, :color, :weight, :fur_quality, :disposition, :sexual_aggression, :has_syphilis # ... etc etc.

具有由方法定义的一长串属性,initialize对于类的每个新实例,这些属性差异很大。

但我发现马达加斯加刺猬总是棕色的,性侵,对梅毒免疫,所以这些属性总是一样的。

MadagascarHedgehogs为了效率,我应该创建一个新类,如果是这样,我如何确定新类继承 ' 属性,只使用类定义中确定的Hedgehogs选择属性?initialize

4

3 回答 3

1

有几种不同的方法可以解决这个问题。我可能会添加一个挂钩方法,您可以从中调用initialize并覆盖您的子类。我还建议使用哈希而不是单独的参数initialize,特别是因为你有这么多变量:

class Hedgehog
  def initialize(attributes = {})
    attributes.each do |key, value|
      instance_variable_set("@#{key}", value)
    end
    set_constant_attributes
  end

  def set_constant_attributes
  end
end

class MadagascarHedgehog
  def set_constant_attributes
    @default1 = 'default value 1'
  end
end

您也可以通过覆盖不使用钩子方法来执行此操作initialize

class MadagascarHedgehog
  def initialize(attributes = {})
    super(attributes)
    @default1 = 'default value 1'
  end
end

但是,我发现这通常不太具有表达性,并且取决于将来谁将阅读/维护此代码,我认为说“在set_constant_attributes方法中定义常量属性”会更容易,而不是信任它们正确覆盖初始化。

第三种方法是重写读取器方法,它简单而简洁(现在我想起来了,可能是我最喜欢的):

class MadagascarHedgehog
  def color
    'brown'
  end
end
于 2013-06-24T21:49:52.540 回答
0

你可以制作一种制造马达加斯加刺猬的方法。

class Hedgehogs
  attr_accessor :name, :age, :color, :weight, :fur_quality, :disposition, :sexual_aggression, :has_syphilis

  def initialize(opts)
    @name = opts[:name] || 'Default Name'
    @age = opts[:age] || 'Default Age'
    ... etc ..
  end

  def self.madagascar_hedgehog
    self.new(:name => 'Madagascar', :age => 50)
  end
end
于 2013-06-24T21:40:16.167 回答
0

首先,我认为你的课程应该是单数的,即HedgehogMadagascarHedgehog

你没有展示你的initialize方法,所以我想你正在传递一个哈希,因为你有很多属性要初始化。

假设你的主类看起来像这样

class Hedgehog

  attr_accessor :name, :age, :color, :weight, :fur_quality, :disposition, :sexual_aggression, :has_syphilis

end

然后你可以在你的子类中编写一个initialize默认常量属性并将值传递给超类以进行实际初始化的方法。

您还可以禁用属性写入访问器,以便这些值不会被覆盖,如果您愿意,可以使用undef_method.

class MadagascarHedgehog < Hedgehog

  def initialize(args)

    args[:color] = 'brown'
    args[:sexual_aggression] = 'aggressive'
    args[:has_syphilis] = 'immune'

    super(args)

  end

  undef_method :color=
  undef_method :sexual_aggression=
  undef_method :has_syphilis=

end
于 2013-06-24T21:53:23.427 回答