具有继承的单例类 - Ruby(我认为)

时间:2015-05-16 21:17:53

标签: ruby singleton class-variables

我试图使用从未实例化的Ruby类,但仍然具有继承的概念。所以看下面的代码,我有课程" Room"允许访问变量而不实例化类(我将它们作为实例变量,但我不确定它是否正确)。

但我希望能够进一步限制" Room"上课分为不同类型的房间。然后我希望每个子类都有自己的变量(@log,@ occpants)。 我该怎么做?

如果我使用类变量,每次更改一个类时都会覆盖它们。

class Room
  @log = []
  @occupants = []

  def self.occupants
    @occupants
  end

  def self.log
    @log
  end

  def self.log_entry(person)
    if @occupants << person
      @log << "#{person.name} entered Office: #{Time.now}"
    end
  end  

  def self.log_exit(person)
    if @occupants.delete(person)
      @log << "#{person.name} exited Office: #{Time.now}"
    end
  end
end

class Office < Room
end

class Kitchen < Room
end

2 个答案:

答案 0 :(得分:1)

根据我的理解,您实际上正在尝试创建一个Abstract类,该类将包含不同类型的Rooms的几个常见属性和行为的实现。是的,我之所以提到它而不是Singleton,因为你想在没有实例化的情况下使用Room,但在Singleton的情况下,会有一个Room实例。

通过在类级别范围内声明变量,如下所示:

class Room
  @log = []
  @occupants = []
  ...
end

您正在设置“类实例变量”而不是“类变量”(具有“@@”前缀的那些)。类实例变量对于该类是唯一的,并且在子类时它们不会被继承。

但是在这种情况下使用类变量也不起作用,因为每个房间都应该有自己的一组占用者和日志。如果使用类变量,则父类及其所有子类将具有相同的公共类变量。

我建议将常见的东西作为实例方法实现,而是使用实例变量。

class Room
  def initialize
    @log = []
    @occupants = []
  end

  def occupants
    @occupants
  end

  def log
    @log
  end

  def log_entry(person)
    if @occupants << person
      @log << "#{person.name} entered Office: #{Time.now}"
    end
  end  

  def log_exit(person)
    if @occupants.delete(person)
      @log << "#{person.name} exited Office: #{Time.now}"
    end
  end
end

class Office < Room
end

class Kitchen < Room
end

编辑: 顺便说一下,你应该用#{self.class}替换日志的输入和退出消息中的“Office”。

答案 1 :(得分:0)

如果这是日志功能,您可能最好创建一个模块,您可以在实例化的Room(和其他)类中添加extend(不包括)以提供额外的静态方法。

image_x, image_y = get_random_coordinates()
while True:
    if time.clock() - last_spawn_time > 6.0:
        image_x, image_y = get_random_coordinates()
        last_spawn_time = time.clock()
    screen.blit(Green, (image_x, image_y))