在Ruby中,有没有办法在子类中“覆盖”一个常量,这样从子类调用一个继承的方法会导致该方法使用新的常量而不是旧的常量?例如:
class SuperClass
CONST = "Hello, world!"
def self.say_hello
CONST
end
end
class SubClass < SuperClass
override_const :CONST, "Hello, Bob!"
end
SuperClass.say_hello # => "Hello, world!"
SubClass.say_hello # => "Hello, Bob!"
如果没有,是否有办法做这样的事情呢?
class SuperClass
CONST = "Hello, world!"
def self.say_hello
CONST
end
end
SubClass = SuperClass.clone
SubClass.send(:remove_const, :CONST)
SubClass.const_set(:CONST, "Hello, Bob!")
SubClass.say_hello # => "Hello, Bob!"
注意:我在irb中尝试了我的第二个例子,它似乎有效,除了在克隆类之后类方法似乎无法访问CONST:
irb(main):012:0> SubClass.say_hello
NameError: uninitialized constant Class::CONST
from (irb):4:in `say_hello'
from (irb):12
from C:/Ruby193/bin/irb:12:in `<main>'
答案 0 :(得分:58)
我通过简单地重新定义子类中的常量,然后在方法中将其引用为实例方法中的self.class::CONST
和类方法中的self::CONST
来完成此操作。在您的示例中:
class SuperClass
CONST = "Hello, world!"
def self.say_hello
self::CONST
end
end
class SubClass < SuperClass
CONST = "Hello, Bob!"
end
SubClass.say_hello #=> "Hello, Bob!"
答案 1 :(得分:2)
你可以在父类中引用这样的常量:
对于实例方法:self.class::CONST
对于自我方法:self::CONST
class SuperClass
CONST = "Hello, world!"
def print_const
puts self.class::CONST
end
def self.print_const
puts self::CONST
end
end
class SubClass < SuperClass
CONST = "Hello, Bob!"
end
SubClass.new.print_const #=> "Hello, Bob!"
SubClass.print_const #=> "Hello, Bob!"
答案 2 :(得分:2)
如果您有能力更改基类,请考虑在基类中包装需要在类方法中进行更改的“常量”,并根据需要在子类中覆盖它们。这消除了父常量和子类常量之间混淆的可能性。对于此示例,如下所示:
class SuperClass
CONST = "Hello, world!".freeze
def self.const
CONST
end
def self.say_hello
const
end
end
class SubClass < SuperClass
CONST = "Hello, Bob!".freeze
def self.const
CONST
end
end
SubClass.say_hello #=> "Hello, Bob!