Разница между классом и объектом в Котлине
Я новичок в Kotlin и недавно преобразовал простой файл из java в Kotlin. Мне интересно, почему Android-конвертер изменил мой класс java на объект Kotlin.
Джава:
public class MyClass {
static public int GenerateChecksumCrc16(byte bytes[]) {
int crc = 0xFFFF;
int temp;
int crc_byte;
for (byte aByte : bytes) {
crc_byte = aByte;
for (int bit_index = 0; bit_index < 8; bit_index++) {
temp = ((crc >> 15)) ^ ((crc_byte >> 7));
crc <<= 1;
crc &= 0xFFFF;
if (temp > 0) {
crc ^= 0x1021;
crc &= 0xFFFF;
}
crc_byte <<= 1;
crc_byte &= 0xFF;
}
}
return crc;
}
}
Преобразованный Котлин:
object MyClass {
fun GenerateChecksumCrc16(bytes: ByteArray): Int {
var crc = 0xFFFF
var temp: Int
var crc_byte: Int
for (aByte in bytes) {
crc_byte = aByte.toInt()
for (bit_index in 0..7) {
temp = crc shr 15 xor (crc_byte shr 7)
crc = crc shl 1
crc = crc and 0xFFFF
if (temp > 0) {
crc = crc xor 0x1021
crc = crc and 0xFFFF
}
crc_byte = crc_byte shl 1
crc_byte = crc_byte and 0xFF
}
}
return crc
}
}
Почему это не так:
class MyClass {
... etc ...
}
Любая помощь будет с благодарностью благодарна.
Ответы
Ответ 1
Объект Kotlin похож на класс, который не может быть создан, поэтому его нужно вызвать по имени. (статический класс как таковой)
Андроид-конвертор увидел, что ваш класс содержит только статический метод, поэтому он преобразовал его в объект Kotlin.
Подробнее об этом читайте здесь: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects
Ответ 2
Документация Котлина об этом довольно хороша, поэтому не стесняйтесь читать это.
Выбранный ответ на этот вопрос имеет некоторые плохие фразеологии в его объяснении и может легко ввести в заблуждение людей. Например, объект не является "статическим классом per-say", а скорее является a static instance of a class that there is only one of
, иначе известный как singleton.
Возможно, лучший способ показать разницу - посмотреть на декомпилированный код Котлина в форме Java.
Вот объект и класс Kotlin:
object ExampleObject {
fun example() {
}
}
class ExampleClass {
fun example() {
}
}
Чтобы использовать ExampleClass
, вам нужно создать его экземпляр: ExampleClass().example()
, но с объектом Kotlin создает для него один экземпляр, и вы никогда не называете его конструктором, вместо этого вы просто ExampleObject.example()
к нему статический экземпляр, используя имя: ExampleObject.example()
.
Вот эквивалентный код Java, который Kotlin будет генерировать:
public final class ExampleObject {
public static final ExampleObject INSTANCE = new ExampleObject();
private ExampleObject() { }
public final void example() {
}
}
public final class ExampleClass {
public final void example() {
}
}
Вы бы использовали объект в Котлине следующим образом:
ExampleObject.example()
Что бы скомпилировать до эквивалентного байтового кода Java для:
ExampleObject.INSTANCE.example()
Основной случай использования object
в Котлине состоит в том, что Котлин пытается покончить со статическими и примитивными, оставив нам чисто объектно-ориентированный язык. Kotlin по-прежнему использует static
и примитивные элементы под капотом, но это препятствует разработчикам использовать эти концепции. Вместо этого теперь Котлин заменяет статические экземпляры объектов singleton. Если раньше вы использовали статическое поле в Java, то в Kotlin вы теперь создадите object
и поместите это поле в object
.
Поскольку Kotlin на 100% совместим с Java, иногда вам нужно выставлять определенные API или поля таким образом, чтобы лучше читать Java. Для этого вы можете использовать аннотацию @JvmStatic
. @JvmStatic
поле или функцию в object
с @JvmStatic
, оно скомпилируется до статических полей, которые Java может использовать проще.
Последнее, что стоит упомянуть, является companion object
s. В Java обычно есть классы с некоторым статическим контентом, а также некоторые нестатические/экземпляры содержимого. Котлин позволяет сделать что - то подобное с сопутствующими объектами, которые являются object
привязан к class
, то есть класс может получить доступ к нему спутник объекта частные функции и свойства:
class ExampleClass {
companion object {
// Things that would be static in Java would go here in Kotlin
private const val str = "asdf"
}
fun example() {
// I can access private variables in my companion object
println(str)
}
}
Ответ 3
Объект является одноэлементным. Вам не нужно создавать экземпляр для его использования.
Необходимо использовать экземпляр класса для использования
Точно так же, как в Java вы можете сказать Math.sqrt(2), и вам не нужно создавать экземпляр Math для использования sqrt, в Kotlin вы можете создать объект для хранения этих методов, и они эффективно статичны.
Здесь есть информация:
https://kotlinlang.org/docs/reference/object-declarations.html
IntelliJ, очевидно, достаточно умен, чтобы обнаружить, что вам нужен объект, поскольку у вас есть только статические java-методы.
Ответ 4
Также вы можете определять функции без объявления объекта. Просто в.kt файле Например:
fun GenerateChecksumCrc16(bytes: ByteArray): Int {
...
}
И эта функция была связана с пакетом, где объявлен файл.kt. Подробнее об этом можно узнать здесь https://kotlinlang.org/docs/reference/packages.html