0

简而言之:我想在继承到所有子类的超类中定义算法,但我想将子类中的数据(算法在其上运行)定义为实例变量,当我调用“新”给定类的方法。在 Ruby 中执行此操作的标准方法是什么?

我的解决方案是(但我不确定这是正确的方法):

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
4

2 回答 2

1

你有什么作品。里面只有一些不需要的东西:

实例变量评估nil它们是否未初始化并且一旦使用它们就会立即存在,因此您的A#initialize方法是不必要的。

您可以覆盖A#var和使用执行完全相同操作的A#var=方法中的Band方法。C没有必要这样做,只需去掉andattr_accessor定义中的调用即可。BC

您创建varvar=访问方法,但您从不使用它们。摆脱对attr_accessor或(最好)使用访问器方法的调用,即使用self.var =ininitializeputs varin 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

[注意:您的编码风格也关闭了。缩进在 Ruby 中是 2 个空格,而不是 3 个。]

但是,如果 的@var所有实例的值始终相同B,那么为什么需要多个实例B

为什么不这样:

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
于 2013-08-05T13:54:26.393 回答
0

您正在以几乎正确的方式进行操作。一个小问题是您的A::initialize定义是多余的,原因有两个:

  • 实例变量被初始化为nil自动。
  • 创建子类实例时,子类中的initialize方法将被覆盖。A::initialize

此外,attr_accessor子类中的调用是多余的。


现在我似乎得到了你想要的。您可以使用类级别的实例变量。

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
于 2013-08-05T13:44:22.367 回答