根据类的名称声明实例变量值是不好的做法吗?

时间:2015-07-14 18:39:40

标签: ruby oop

让我们说我有几个继承自这样的基类的子类:

class Base

  def initialize
    @name = self.class.name
    @num1 = 10;
    @num2 = 5;
  end

  def speak
    puts "My name is #{name}"
  end

end

class Sub1 < Base
end

class Sub2 < Base
end

class Sub3 < Base
end

@name的实例变量声明为类的名称是不好的做法?做这样的事情会更好吗?

class Base

  def initialize
    @feet = 10;
    @inches = 5;
  end

  def speak
    puts "My name is #{name}"
  end

end

class Sub1 < Base
  def initialize
    super()
    @name = "Sub1"
  end
end

class Sub2 < Base
  def initialize
    super()
    @name = "Sub2"
  end
end

class Sub3 < Base
  def initialize
    super()
    @name = "Sub3"
  end
end

3 个答案:

答案 0 :(得分:0)

第一种方法更简洁。您可能应该做的是以懒惰的身份对此进行评估:

def name
  @name ||= self.class.to_s.split(/::/).last
end

这样你就不必担心赋值,任何子类都可以在必要时使用覆盖进行初始化。您的speak方法将继续有效,无需修改,因为您可能已声明attr_reader :name首先使用该方法。

答案 1 :(得分:0)

我认为这是毫无意义的,看看这个输出:

class Base
   def name
     self.class.name
   end
end

class Sub1 < Base
  # This declaration is useless
  def name
    self.class.name
  end
end

class Sub2 < Base
end

b = Base.new
b.name # "Base"

c = Sub1.new
c.name # "Sub1"

d = Sub2.new
d.name # "Sub2" (this function is inherited from base, but is called from Sub2 class context)

在ruby中,您可以使用超类方法获取父类名称

 Sub2.superclass.name # "Base"

答案 2 :(得分:0)

如果df$x <- paste0("'", df$x, "',") 始终等于班级名称,则您不需要它 - 只需直接使用@nameself.class.name,或定义一个访问者方法,如果您不想从外部使用myObject.class.name,请将其退回。手动初始化它将是不好的做法,因为您总是必须记住在每个子类中执行它,并且需要将对子类名称的更改复制到初始化。

如果.class.name 总是等于每个子类中的类名,那么我个人仍然会提供一个默认实现,它从{{1}初始化并且让子类根据需要覆盖它。