如何解决有没有一种方法可以使变量的仅一个类从另一类继承?
我是新手,也许我在搜索中错过了一些内容,但是我浏览了文档以及此处的其他问题,但没有找到问题的答案,因此,请把它放在这里,如果对不起,请原谅它已经在其他地方进行了解释。 我在ruby中有两个类,一个叫做Animal,另一个是Animal_Group。在Animal的初始化中,我有一个名为@family的变量,我想将此变量与Animal_Group的现有实例进行比较,如果有匹配项,我希望它继承定义(包括Animal_Group类的值初始化)变量本身)类Animal_Group及其实例。
只是说明一下,就像这样:
class Animal
def initialize(ident,species,family,age)
@ident = ident
@species = species
@family = family
if family.class == Animal_Group
super(*args)
end
@age = age
end
end
所以它会导致类似这样的结果:
- 我创建了一个动物“套件”,是“猫”家族中年龄7岁的“猫”。
- 有一个Animal_Group实例,名为“猫科动物”,变量@lifespan ='17',@ environment_sphere ='terrestrial'和@breed_max ='6'
- 'kit'将使它们具有变量,其值如下:
@ident = 'kit' @species = 'cat' @family = 'feline' @age = '7' @lifespan = '17' @environment_sphere = 'terrestrial' @breed_max = '6'
有没有办法做到这一点,或者唯一的办法就是将所有内容都转换为新类?
解决方法
基本上,没有元编程,那么这是不可能的。尽管我可以展示如何使用元编程来做到这一点,但我会将其作为练习留给读者,因为当涉及到它时,最好使事情保持简单,并且肯定有一种更简单的方法。
无论如何,我推荐的系统是这样的:
class AnimalGroup
attr_reader :lifespan,:environment_sphere,:breed_max,:age
end
class Feline < AnimalGroup
def initialize
@lifespan = '17'
@environment_sphere = 'terrestrial'
@breed_max = '6'
end
end
class Cat < Feline
def initialize(age)
@age = age
super
end
end
我知道这似乎比您要编写的代码灵活一些。与其将动物组的“类型”存储为动态实例变量,我们基本上是使用类定义对其进行硬编码。但希望您能看到这种方法更简单。
,假设
class Animal_Group
attr_reader :name,:lifespan,:breed_mix
def initialize(name,lifespan,breed_mix)
@name = name
@lifespan = lifespan
@breed_mix = breed_mix
end
end
Animal_Group.new("Boots",18,"Siamese")
#=> #<Animal_Group:0x000056fa3111a878 @name="Boots",@lifespan=18,# @breed_mix="Siamese">
Animal_Group.new("Hank",14,"Tabby")
#=> #<Animal_Group:0x000056fa3114f618 @name="Hank",@lifespan=14,# @breed_mix="Tabby">
我假设family
中参数Animal.new
的实例将是'Boots'
或'Hank'
,如
Animal.new('kit','Hank',7)
如果我误解了这个问题,没有理由进一步阅读。
可以使用两种方法来使用Animal_Group
实例中的信息来为Animal
实例的实例变量分配值。在这两种情况下,诀窍都是要找到{_1}}实例,其instance_variable Animal_Group
的值等于@name
family
的值。
Animal.new
class Animal
def initialize(ident,family,age)
@ident = ident
@family = family
@age = age
family_instance = ObjectSpace.each_object(Object).find do |o|
o.class == Animal_Group && o.name == family
end
# raise exception here if family_instance is nil
@lifespan = family_instance.lifespan
@breed_mix = family_instance.breed_mix
end
end
维护Animal.new('kit',7)
#=> #<Animal:0x000056fa31211f10 @ident="kit",@family="Hank",# @age=7,@breed_mix="Tabby">
Animal.new('kat','Boots',4)
#=> #<Animal:0x000056fa31174918 @ident="kat",@family="Boots",# @age=4,@breed_mix="Siamese">
的实例列表
Animal_Group
请注意
class Animal_Group
@name_to_instance = {}
singleton_class.public_send(:attr_reader,:name_to_instance)
attr_reader :name,breed_mix)
@name = name
@lifespan = lifespan
@breed_mix = breed_mix
self.class.name_to_instance[name] = self
end
end
(其中singleton_class.public_send(:attr_reader,:name_to_instance)
)为类实例变量self #=> Animal_Group
创建一个读取访问器,该变量具有将实例名称映射到实例的哈希。
@name_to_instance
注意
Animal_Group.new("Boots","Siamese")
#=> #<Animal_Group:0x000056fa311b6110 @name="Boots","Tabby")
#=> #<Animal_Group:0x000056fa311e9998 @name="Hank",# @breed_mix="Tabby">
Animal_Group.name_to_instance
#=> {"Boots"=>#<Animal_Group:0x000056fa311b6110 @name="Boots",# @lifespan=18,@breed_mix="Siamese">,# "Hank"=>#<Animal_Group:0x000056fa311e9998 @name="Hank",# @lifespan=14,@breed_mix="Tabby">}
class Animal
def initialize(ident,age)
@ident = ident
@family = family
@age = age
family_instance = Animal_Group.name_to_instance[family]
# raise exception here if family_instance is nil
@lifespan = family_instance.lifespan
@breed_mix = family_instance.breed_mix
end
end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。