Простой ответ заключается в том, что вы не можете расширять перечисления в Kotlin так, как вам бы хотелось.
Я должен согласиться с комментарием Miha_x64 о том, что наследование является "злом" и должно использоваться только тогда, когда онозаконно имеет смысл (да, все еще существуют ситуации, когда наследование - это путь).Я считаю, что вместо того, чтобы пытаться обойти дизайн перечислений в Kotlin, почему бы не разработать наше решение иначе?Я имею в виду: почему вы думаете, что вам нужна такая иерархия перечислений, для начала?В чем выгода?Почему бы просто не иметь некоторые "общие ошибки", а конкретные ошибки для конкретной области, требующей особых ошибок?Зачем даже использовать перечисления?
Если вы не можете использовать перечисления, то решение Januson может быть вашим лучшим выбором, но, пожалуйста, используйте значимые коды ошибок, потому что "1001", "1002", "233245"и так ужасно читать и работать с ними.Я нахожу "INTERNET_ERROR" и "BLUETOOTH_ERROR" и т. Д. Просто загадочными ... можем ли мы на самом деле не делать ничего лучше и быть более конкретными в отношении того, что пошло не так, чтобы тот, кто читает код ошибки, мог на самом деле понять, что не так, без необходимости копатьчерез интернет или через какую-то здоровенную документацию на следующие несколько минут / часов?(за исключением, конечно, если есть некоторые законные причины, по которым код должен быть как можно меньшего размера - например, ограничения размера сообщения, ограничения полосы пропускания и т. д.)
В случае, если вы не устали использовать перечисления, тогда вы могли бы рассмотреть следующее:
data class ErrorCode(
val code: String,
val localeKey: String,
val defaultMessageTemplate: String
)
val TENANT_ACCESS_FORBIDDEN = ErrorCode(
"TENANT_ACCESS_FORBIDDEN",
"CommonErrorCodes.TENANT_ACCESS_FORBIDDEN",
"Not enough permissions to access tenant ''{0}''."
)
val NO_INTERNET_CONNETION = ErrorCode(
"NO_INTERNET_CONNETION",
"DeviceErrorCodes.NO_INTERNET_CONNETION",
"No internet connection."
)
val NO_BLUETOOTH_CONNECTION = ErrorCode(
"NO_BLUETOOTH_CONNECTION",
"DeviceErrorCodes.NO_BLUETOOTH_CONNECTION",
"No bluetooth connection."
)
val TEMPERATURE_THRESHOLD_EXCEEDED = ErrorCode(
"TEMPERATURE_THRESHOLD_EXCEEDED",
"DeviceErrorCodes.TEMPERATURE_THRESHOLD_EXCEEDED",
"Temperature ''{0}'' exceeds the maximum threshold value of ''{1}''."
)
Поскольку все вышеприведенные коды, по сути, действуют как статические константы, сравнивать их так же просто, как сравнивать перечисления (например: if (yourException.errorCode == NO_INTERNET_CONNECTION) { // do something }
).
Наследование действительно не нужно, действительно нужно четкое разделение между общими и нечастыми кодами ошибок.