UPD
在更新的編碼約定,有一個section on this topic:
廠功能
如果要聲明一個類工廠功能,避免給它相同名稱作爲類本身。首選使用明確的名稱,明確爲什麼工廠功能的行爲是特殊的。只有在沒有特殊的語義時,纔可以使用與該類相同的名稱。
例子:
class Point(val x: Double, val y: Double) {
companion object {
fun fromPolar(angle: Double, radius: Double) = Point(...)
}
}
我下面所描述的動機,不過,似乎仍持有。
正如有關naming style文件說:
如有疑問默認的Java編碼約定,如:
一個強大的理由t Ø避免命名相同的一類功能是,它可能混淆開發誰以後會使用它,因爲,違背了他們的期望:
- 功能將無法使用超級構造函數調用(如果類被
open
)
- 它不會通過反射
- 構造可見它不能用作Java代碼構造(
new HashSet(n, it -> "Element " + it)
是錯誤的) ,如果你想以後更改實施
- 和反而會返回一些子類實例,它會變得更加令人困惑,即
HashSet(n) { "Element $it" }
將會升結構不是HashSet
但是,例如LinkedHashSet
最好是明確的,這是一個工廠函數,而不是一個構造函數表現出來,爲了避免這種混亂。
在stdlib中通常也避免了爲一個類命名相同的功能。鑑於SomeClass
,在stdlib中,工廠函數的首選命名方式是someClassOf
,someClassBy
或任何可以最好地解釋函數的語義。例子:
generateSequence { ... }
和sequenceOf(...)
lazy { ... }
和lazyOf(...)
compareBy { ... }
listOf(...)
,setOf(...)
,mapOf(...)
因此,人們非常需要有強有力的理由來有一個函數模仿構造函數。
相反,函數的名稱可能會告訴用戶更多(甚至是全部)關於它的用法。
真的嗎?那麼現在二級構造函數比工廠函數更好?我認爲我們需要官方意見(在文檔中) – voddan
@voddan,問題和答案不是關於次要構造函數,而是關於讓函數模仿構造函數。什麼是次要構造函數,當函數應該返回具有不同實現的子類實例時,它們是沒有用的。否則,它們似乎比工廠功能更好(反射,超級調用,Java互操作)。 – hotkey
好吧,像類一樣命名的函數的唯一建議是在不溢出類代碼的情況下對這些類進行因式分解。另一種選擇是次要的構造函數,它在你的答案中隱含着。 – voddan