[英]Difference between a class and object in Kotlin
我是 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;
}
}
轉換后的 Kotlin:
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 ...
}
任何幫助將不勝感激,謝謝。
為這個問題選擇的答案在解釋上有一些不好的措辭,很容易誤導人們。 例如,一個對象本身並不是“靜態類”,而是a static instance of a class that there is only one of
,也稱為單例。
或許顯示差異的最好方法是查看 Java 形式的反編譯 Kotlin 代碼。
Kotlin 對象和類:
object ExampleObject {
fun example() {
}
}
class ExampleClass {
fun example() {
}
}
為了使用ExampleClass
,您需要創建它的一個實例: ExampleClass().example()
,但是對於一個對象,Kotlin 會為您創建它的一個實例,並且您永遠不會調用它的構造函數,而是您只需使用名稱訪問它的靜態實例: ExampleObject.example()
。
Kotlin 會生成等價的 Java 代碼:
Kotlin 編譯為 Java 字節碼,但是如果我們將上面編譯的 Kotlin 代碼反向編譯為 Java 代碼,我們會得到:
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() {
}
}
您可以通過以下方式在 Kotlin 中使用該對象:
ExampleObject.example()
這將編譯為等效的 Java 字節碼:
ExampleObject.INSTANCE.example()
Kotlin 為什么要引入object
?
Kotlin 中object
的主要用例是因為 Kotlin 試圖取消靜態和原語,給我們留下一種純粹的面向對象語言。 Kotlin 仍然在幕后使用static
和原語,但它不鼓勵開發人員再使用這些概念。 相反,現在 Kotlin 用單例對象實例替換了靜態。 以前在 Java 中使用靜態字段的地方,在 Kotlin 中,您現在將創建一個object
,並將該字段放入object
。
與 Java 的互操作性:
由於 Kotlin 與 Java 100% 可互操作,因此有時您會希望以更便於 Java 閱讀的方式公開某些 API 或字段。 為此,您可以使用@JvmStatic
注釋。 通過注釋字段或一個函數object
與@JvmStatic
,它將編譯到靜態字段的Java可以使用更方便。
伴生對象:
值得一提的最后一件事是companion object
。 在 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)
}
}
Kotlin 對象就像一個無法實例化的類,因此必須按名稱調用它。 (一個靜態類本身)
android 轉換器看到您的類僅包含一個靜態方法,因此將其轉換為 Kotlin 對象。
在此處閱讀更多相關信息: http : //petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects
一個對象是一個單例。 您無需創建實例即可使用它。
需要實例化一個類才能使用
就像在 Java 中你可以說 Math.sqrt(2) 一樣,你不需要創建一個 Math 實例來使用 sqrt,在 Kotlin 中你可以創建一個對象來保存這些方法,它們實際上是靜態的。
這里有一些信息:
https://kotlinlang.org/docs/reference/object-declarations.html
IntelliJ 顯然足夠聰明,可以檢測到您需要一個對象,因為您只有靜態 Java 方法。
之間的區別:對象|| 類|| 伴生對象|| 數據類
object MyClass{}
,整個變量具有單一引用,但在companion object
您可以選擇創建靜態方法或創建靜態變量equals()
、 hashCode()
和toString()
例子
//---------------1- object ----------------------
object MyClass1 {
fun checkData {
// ...
}
}
MyClass1.checkData() // call method
//----------------2- class ---------------------
class MyClass2 {
fun checkData {
// ...
}
}
var myClass = MyClass2()
myClass.checkData() // call method
//----------------3- companion object ---------------------
class MyClass3 {
companion object {
fun myStaticMethod() {
// ...
}
}
fun myInstanceMethod() {
// ...
}
}
MyClass3.myStaticMethod() // call companion object member
var myClass = MyClass3()
myClass.myInstanceMethod() // call simple method using reference
//----------------4- data class ---------------------
data class MyClass4(val name: String, val rId: Int)
您也可以在沒有對象聲明的情況下定義函數。 只是在 .kt 文件中例如:
fun GenerateChecksumCrc16(bytes: ByteArray): Int {
...
}
這個函數與聲明 .kt 文件的包有關。 你可以在這里閱讀更多關於它的信息https://kotlinlang.org/docs/reference/packages.html
基於@speirce7 的回答:
以下代碼顯示了 Kotlin 中類和對象之間的基本區別:
class ExampleClass(){
fun example(){
println("I am in the class.")
}
}
object ExampleObject{
fun example(){
println("I am in the object.")
}
}
fun main(args: Array<String>){
val exampleClass = ExampleClass() // A class needs to be instantiated.
exampleClass.example() // Running the instance of the object.
ExampleObject.example() // An object can be thought of as a Singleton and doesn't need any instantiation.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.