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

Singleton classes with inheritance - Ruby ( I think)

我正在尝试使用从未实例化的 Ruby classes,但仍然有 inheritance.So 的概念 查看下面的代码,我有 class "Room" 允许在不实例化 class 的情况下访问变量(我将它们作为实例变量,但我不确定这是正确的)。

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

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

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

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

module Logger
  def log_item(person)
    logger.debug "#{person.name} entered Office: #{Time.now}"
  end
end

class Room
  extend Logger
  @log = [] #you could use this to collect statements then log at a later time? otherwise I'm not sure why you would take this approach.
  @occupants = []

  def self.log_entry(person)
    if @occupants << person
      log_item(person)
    end
  end
end

据我了解,您实际上是在尝试创建一个抽象 class 来保存不同类型房间的一些常见属性和行为的实现。是的,我提到它是 Abstract 而不是 Singleton,因为您想在不实例化它的情况下使用 Room,但在 Singleton 的情况下,只有一个 Room 实例。

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

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

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

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

我建议将常见的东西实现为实例方法并改用实例变量。

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

编辑: 顺便说一句,您应该将日志的输入和退出消息中的 'Office' 替换为 #{self.class}.