In Ruby is there a way to overload the initialize constructor?
在爪哇中,可以重载构造函数:
1 2 3 4 5 6 | public Person(String name) { this.name = name; } public Person(String firstName, String lastName) { this(firstName +"" + lastName); } |
Ruby中是否有实现相同结果的方法:两个采用不同参数的构造函数?
答案是"是"和"否"。
您可以使用各种机制在其他语言中实现相同的结果,包括:
- 参数的默认值
- 变量参数列表(splat运算符)
- 把你的论点定义为散列
语言的实际语法不允许您定义两次方法,即使参数不同。
考虑到上面的三个选项,可以用下面的示例实现这些选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # As written by @Justice class Person def initialize(name, lastName = nil) name = name +"" + lastName unless lastName.nil? @name = name end end class Person def initialize(args) name = args["name"] +"" + args["lastName"] unless args["lastName"].nil? @name = name end end class Person def initialize(*args) #Process args (An array) end end |
号
您将经常在Ruby代码中遇到第二种机制,特别是在Rails中,因为它提供了两种最好的机制,并且允许一些语法上的优势来生成漂亮的代码,特别是不必将传递的哈希包含在大括号中。
这个wikibooks链接提供了更多的阅读
我喜欢这样
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person def self.new_using_both_names(first_name, last_name) self.new([first_name, last_name].join("")) end def self.new_using_single_name(single_name) self.new(single_name) end def initialize(name) @name = name end end |
但我不知道这是不是最好的方法。
1 2 3 4 5 6 | class Person def initialize(name, lastName = nil) name = name +"" + lastName unless lastName.nil? @name = name end end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class StatementItem attr_reader :category, :id, :time, :amount def initialize(item) case item when Order initialize_with_order(item) when Transaction initialize_with_transaction(item) end end def valid? !(@category && @id && @time && @amount).nil? end private def initialize_with_order(order) return nil if order.status != 'completed' @category = 'order' @id = order.id @time = order.updated_at @amount = order.price end def initialize_with_transaction(transaction) @category = transaction.category @id = transaction.id @time = transaction.updated_at @amount = transaction.amount end end |
。
您可以使用konstructor gem在ruby中声明多个构造函数并模拟重载:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person def initialize(name) @name = name end konstructor def from_two_names(first_name, last_name) @name = first_name + ' ' + last_name end end Person.new('John Doe') Person.from_two_names('John', 'Doe') |
签出功能性的Ruby Gem,它的灵感来自于长生不老的模式匹配特性。
1 2 3 4 5 6 | class Foo include Functional::PatternMatching defn(:initialize) { @name = 'baz' } defn(:initialize, _) {|name| @name = name.to_s } end |
。
我通常这样做:
1 2 3 4 5 6 7 8 9 10 11 12 | class Person attr_reader :name def initialize(first: nil, last: nil) @name = [first, last].compact.join(' ') end end Person.new(first: 'ya').name # =>"ya" Person.new(first: 'ya', last: 'ku').name # =>"ya ku" |
。