我有一个类似于这样开始的课程:
class Hedgehogs
attr_accessor :name, :age, :color, :weight, :fur_quality, :disposition, :sexual_aggression, :has_syphilis # ... etc etc.
具有由方法initialize
定义的长属性列表,这些属性因类的每个新实例而异。
但我发现马达加斯加刺猬总是棕色,性侵略性,对梅毒免疫,所以这些属性总是一样的。
我是否应该为了效率而创建一个新类MadagascarHedgehogs
,如果是这样,我如何确定新类继承Hedgehogs
'属性,仅使用来自initialize
的select属性而在类定义中呢?
答案 0 :(得分: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
方法中定义常量属性会更容易',而不是相信他们正确地覆盖init。
第三种方法是覆盖读者方法,这很简单,很简洁(现在我想起来,可能是我最喜欢的):
class MadagascarHedgehog
def color
'brown'
end
end
答案 1 :(得分: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
答案 2 :(得分:0)
首先,我认为您的课程应该是单数的,即Hedgehog
和MadagascarHedgehog
。
你没有显示你的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