Leo*_*sov 52 ruby constructor access-specifier
class A
private
def initialize
puts "wtf?"
end
end
A.new #still works and calls initialize
Run Code Online (Sandbox Code Playgroud)
和
class A
private
def self.new
super.new
end
end
Run Code Online (Sandbox Code Playgroud)
不起作用
那么正确的方法是什么?我想new私有化并通过工厂方法调用它.
adu*_*ity 77
试试这个:
class A
private_class_method :new
end
Run Code Online (Sandbox Code Playgroud)
Nat*_*han 13
您尝试的第二块代码几乎是正确的.问题是private在实例方法而不是类方法的上下文中操作.
要获得private或private :new工作,您只需要强制它在类方法的上下文中,如下所示:
class A
class << self
private :new
end
end
Run Code Online (Sandbox Code Playgroud)
或者,如果你真的想重新定义new并打电话super
class A
class << self
private
def new(*args)
super(*args)
# additional code here
end
end
end
Run Code Online (Sandbox Code Playgroud)
类级工厂方法可以正常访问私有new,但尝试直接使用实例化new将失败,因为它new是私有的.
为了阐明用法,以下是工厂方法的常见示例:
class A
def initialize(argument)
# some initialize logic
end
# mark A.new constructor as private
private_class_method :new
# add a class level method that can return another type
# (not exactly, but close to `static` keyword in other languages)
def self.create(my_argument)
# some logic
# e.g. return an error object for invalid arguments
return Result.error('bad argument') if(bad?(my_argument))
# create new instance by calling private :new method
instance = new(my_argument)
Result.new(instance)
end
end
Run Code Online (Sandbox Code Playgroud)
然后将其用作
result = A.create('some argument')
Run Code Online (Sandbox Code Playgroud)
如预期的那样,在直接new使用的情况下会发生运行时错误:
a = A.new('this leads to the error')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15750 次 |
| 最近记录: |