[英]How should I define an instance variable in Ruby whose processing algorithm is defined in a super class?
In short: I want to define the algorithm in the superclass which inherits into all subclasses, but I want to define the data (on which the algorithm operates) in the subclasses as instance variables, which come into being when I call the "new" method of the given classes. 简而言之:我想在继承到所有子类的超类中定义算法,但是我想在子类中将数据(算法在其上进行操作)定义为实例变量,这些实例变量是在我调用“ new”时产生的给定类的方法。 What is the standard way for doing this in Ruby? 在Ruby中执行此操作的标准方法是什么?
My solution is (but I am not exactly sure this is the right way): 我的解决方案是(但是我不确定这是正确的方法):
class A
attr_accessor :var
def initialize
@var=nil #I dont know the actual value, it will be defined only in the more specific subclasses.
end
def process_data
puts @var #simply puts it out
end
end
#in my program all further classes are inherited form class A, the processing facility is inherited, only the data varies.
class B < A
attr_accessor :var
def initialize
@var=10 #specific value for class B which is always 10, no need for example b=B.new(20)
end
end
class C < A
attr_accessor :var
def initialize
@var=20 #specific value for class C which is always 20, no need for example c=C.new(20)
end
end
b=B.new
b.process_data #needs to print 10
c=C.new
c.process_data #needs to print 20
What you have works. 您所拥有的作品。 There's just some unneeded stuff in there: 那里只有一些不需要的东西:
Instance variables evaluate to nil
if they are uninitialized and they spring into existence as soon as they are used, so your A#initialize
method is unnecessary. 如果实例变量未初始化,则其求值为nil
,并且一旦使用它们便会立即存在,因此不需要A#initialize
方法。
You override the A#var
and A#var=
methods in B
and C
with methods that do the exact same thing. 使用执行完全相同的操作的方法覆盖B
和C
的A#var
和A#var=
方法。 There is no need for that, just get rid of the calls to attr_accessor
in the definition of B
and C
. 不需attr_accessor
,只需摆脱B
和C
定义中对attr_accessor
的调用。
You create var
and var=
accessor methods but you never use them. 您创建了var
和var=
访问器方法,但从未使用过它们。 Either get rid of the call to attr_accessor
or (preferably) use the accessor methods, ie use self.var =
in initialize
and puts var
in process_data
. 摆脱对attr_accessor
的调用,或者(最好)使用accessor方法,即在initialize
使用self.var =
puts var
放入process_data
。
class A
attr_accessor :var
def process_data
puts var #simply puts it out
end
end
#in my program all further classes are inherited form class A, the processing facility is inherited, only the data varies.
class B < A
def initialize
self.var = 10 #specific value for class B which is always 10, no need for example b=B.new(20)
end
end
class C < A
def initialize
self.var = 20 #specific value for class C which is always 20, no need for example c=C.new(20)
end
end
b = B.new
b.process_data #needs to print 10
c = C.new
c.process_data #needs to print 20
[Note: your coding style was also off. [注意:您的编码风格也已关闭。 Indentation is 2 spaces in Ruby, not 3.] 缩进在Ruby中为2个空格,而不是3个空格。]
However, if the value of @var
is always the same for all instances of B
, then why do you need multiple instances of B
? 但是,如果对于B
所有实例,@ @var
的值始终相同,那么为什么需要多个B
实例?
Why not something like this: 为什么不这样:
class A
attr_accessor :var
def initialize(val)
self.var = val
end
def process_data
puts var #simply puts it out
end
end
b = A.new(10)
b.process_data #needs to print 10
c = A.new(20)
c.process_data #needs to print 20
You are doing it in almost the right way. 您正在以几乎正确的方式进行操作。 A minor point is that your A::initialize
definition is redundant for two reasons: 还有一点要注意的是,您的A::initialize
定义是多余的,原因有两个:
nil
automatically. 实例变量自动初始化为nil
。 initialize
methods in the subclasses will override A::initialize
when the subclass instances are created. 创建子类实例时,子类中的initialize
方法将覆盖A::initialize
。 Also, the attr_accessor
calls in the subclasses are redundant. 同样,子类中的attr_accessor
调用是多余的。
Now I seem to get what you wanted. 现在我似乎得到了您想要的。 You can use class-level instance variables. 您可以使用类级别的实例变量。
class A
def initialize
@var=self.class.instance_variable_get(:@var)
end
def process_data
puts @var
end
end
class B < A
@var = 10
end
class C < A
@var = 20
end
B.new.process_data # => 10
C.new.process_data # => 20
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.