Ruby 基于类的名称声明实例变量值是一种不好的做法吗?
假设我有两个子类继承自基类,如下所示:Ruby 基于类的名称声明实例变量值是一种不好的做法吗?,ruby,oop,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 第一种
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
第一种方法更简洁。您可能应该做的是以懒散的方式对此进行评估:
def name
@name ||= self.class.to_s.split(/::/).last
end
这样,您就不必担心赋值问题,任何子类都可以在必要时通过重写进行初始化。您的
speak
方法将继续工作,无需修改,因为您可能首先声明了attr\u reader:name
,以使其工作。我认为这是毫无意义的,请查看以下输出:
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)
如果
@name
总是要与类名相等,则不需要它–只需直接使用self.class.name
或myObject.class.name
,或者定义一个访问器方法,如果不想从外部使用.class.name
,则返回它。手动初始化它将是一种糟糕的做法,因为您必须始终记住在每个子类中进行初始化,并且对子类名称的更改需要复制到初始化中
如果
@name
并不总是等于每个子类中的类名,那么我个人仍然会提供一个默认实现,在该实现中,它是从self.class.name
初始化的,并根据需要让子类覆盖它。出于好奇,为什么还要将类名分配给ivar呢?已经知道了;我只需要定义一个name
访问器,它返回self.class.name
。当您可以从外部使用self.class.name
或myObject.class.name
时,为什么需要@name=self.class.to
访问器呢?请注意,如果您将Sub1
的倒数第二行替换为@name=self.class.to
,那么Sub1.new.instance_variable_get(:@name)#=>“Sub1”
。(您可以改为编写…instance\u variable\u get('@name')
)。
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)
Sub2.superclass.name # "Base"