(представьте себе, что я могу идентифицировать пользователя по имени или числовым идентификатором)
Вы почти наверняка не хотите, чтобы это сделать, имея дополнительные поля в классе. Скорее, вы должны кодировать тот факт, что пользователь по-разному идентифицирует типы и структуру вашей программы.
Один из способов сделать это, чтобы закодировать идентификатор пользователя, используя Scala встроенный Either
типа:
class User private(identifier : Either[String, Int]) {
def this(id : Int) = this(Right(id))
def this(name : String) = this(Left(name))
}
Однако, вы также можете захотеть сделать характер идентификатора пользователя немного более явным, и кодировать его как свой собственный Algebraic data type:
trait UserIdentifier
object UserIdentifier {
case class ById(id : Int) extends UserIdentifier
case class ByName(name : String) extends UserIdentifier
}
class User(id : UserIdentifier) {
def this(id : Int) = this(UserIdentifier.ById(id))
def this(name : String) = this(UserIdentifier.ByName(name))
}
делая это таким образом, предотвратить такие проблемы, как кто-то пытается искать имя на пользователя, который идентифицируется идентификатором вместо этого. Второй подход также позволяет расширить идею UserIdentifier
в будущем, если пользователь может быть идентифицирован какой-либо другой конструкцией.
Между этими двумя случаями нет реальной разницы; не имеют конфликтов перегрузки. Я не уверен, что не делает то, что вы хотите или ожидаете, или, действительно, какая именно проблема вы столкнулись. –