web-dev-qa-db-ja.com

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

私は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;
    }
}

変換されたコトリン:

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

どんな助けも大歓迎です。

71
Crunchy234

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

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

詳細はこちらをご覧ください: http://petersommerhoff.com/dev/kotlin/kotlin-for-Java-devs/#objects

73
Headline

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

この質問に選ばれた答えは、説明にいくつかの貧弱な表現があり、人々を容易に誤解させる可能性があります。たとえば、オブジェクトは「静的クラスごと」ではなく、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はオブジェクトを使用してそのインスタンスを1つ作成し、コンストラクターを呼び出すことはなく、代わりに静的インスタンスにアクセスします名前を使用して:ExampleObject.example()

コトリンが生成する同等の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はobjectsを導入するのですか?

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

Javaとの相互運用性:

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

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

最後に言及する価値があるのはcompanion objectsです。 Javaでは、通常、静的コンテンツだけでなく非静的/インスタンスコンテンツも含むクラスがあります。 Kotlinでは、objectに結び付けられたclasssであるコンパニオンオブジェクトで同様のことができます。これは、クラスがコンパニオンオブジェクトのプライベート関数とプロパティにアクセスできることを意味します。

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)
  }
}
102
spierce7

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

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

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

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

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

IntelliJは、静的なJavaメソッドしか持っていないため、オブジェクトが必要であることを検出できるほどスマートであることが明らかになっています。

10
Bruce Lowe

また、オブジェクト宣言なしで関数を定義できます。ちょうど.ktファイルの例:

fun GenerateChecksumCrc16(bytes: ByteArray): Int {
    ...
}

そして、この関数は.ktファイルが宣言されているパッケージに関連していました。詳細についてはこちらをご覧ください https://kotlinlang.org/docs/reference/packages.html

3
Silvestr

@ 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.
}
2
Raj