Kotlinのクラスとオブジェクトの違い


98

私はKotlinを初めて使用し、最近、単純なファイルをjavaからKotlinに変換しました。なぜAndroidコンバーターがJavaクラスをKotlinオブジェクトに変更したのかと思います。

Java:

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 ...
}

どんな助けにも感謝します。

回答:


96

Kotlinオブジェクトはインスタンス化できないクラスのようなものなので、名前で呼び出す必要があります。(静的クラス自体)

Androidコンバーターは、クラスに静的メソッドのみが含まれていることを確認したため、それをKotlinオブジェクトに変換しました。

詳しくは、http//petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objectsをご覧ください。


164

これに関するKotlinのドキュメントはかなり良いので、お気軽に読んでください。

この質問に対して選択された答えは、その説明にいくつかの不適切な表現があり、人々を簡単に誤解させる可能性があります。たとえば、オブジェクトは「静的クラス自体」ではなく、「a static instance of a class that there is only one ofシングルトン」とも呼ばれます。

おそらく、違いを示す最良の方法は、逆コンパイルされたKotlinコードをJava形式で確認することです。

Kotlinオブジェクトとクラス:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

を使用するにはExampleClass、そのインスタンスを作成する必要がありますExampleClass().example()。ただし、オブジェクトを使用すると、Kotlinがインスタンスを1つ作成し、コンストラクターを呼び出さずに、静的インスタンスにアクセスします。名前:ExampleObject.example()

同等のJavaコードはKotlinが生成します。

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はなぜobjectsを導入するのですか?

objectKotlin の主な使用例は、Kotlinが静的なプリミティブを取り除こうとするため、純粋にオブジェクト指向の言語が残されるためです。Kotlinはまだstaticフードの下でプリミティブを使用していますが、開発者がこれらの概念を使用することをやめさせます。代わりに、Kotlinはstaticをシングルトンオブジェクトインスタンスに置き換えます。以前はJavaで静的フィールドを使用していましたが、Kotlinでを作成しobject、そのフィールドをに配置しますobject

Javaとの相互運用性:

KotlinはJavaと100%相互運用できるため、Javaが読みやすい方法で特定のAPIまたはフィールドを公開したい場合があります。これを行うには、@JvmStaticアノテーションを使用できます。objectwith @JvmStaticでフィールドまたは関数に注釈を付けると、Javaがより簡単に使用できる静的フィールドにコンパイルされます。

コンパニオンオブジェクト:

言及する価値がある最後の1つはcompanion objectsです。Javaでは、通常、いくつかの静的コンテンツを持つクラスだけでなく、一部の非静的/インスタンスコンテンツも含まれます。Kotlinを使用すると、に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)
  }
}

6
いい説明。どうもありがとう。
デンマーク語のAnsari、

12

オブジェクトはシングルトンです。使用するためにインスタンスを作成する必要はありません。

クラスを使用するにはインスタンス化する必要があります

JavaでMath.sqrt(2)と言うのと同じように、sqrtを使用するためにMathインスタンスを作成する必要はありません。Kotlinでは、これらのメソッドを保持するオブジェクトを作成でき、それらは事実上静的です。

ここにいくつかの情報があります:

https://kotlinlang.org/docs/reference/object-declarations.html

IntelliJは、静的なJavaメソッドしか持っていないので、オブジェクトが必要であることを検出するのに十分賢いことは明らかです。


ちょっと待ってください。でも、クラスHumanに静的なintフィールドがある場合、PopulationKotlinではどのように見えるでしょうか。companion object { @JvmField val Population; }か何か?
Squirrelkiller


1

@ 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.
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.