章IV(クラス、オブジェクト、およびインターフェイス)

Javaクラスとインターフェイスを持つKotlinクラスとインタフェースはまだ少し異なっています。例:インターフェースは、プロパティ宣言を含めることができます。Javaのとは異なり、デフォルトのKotlinが宣言されてfinal とpublic 。また、デフォルトのクラスは、内部クラスをネストされていない。彼らはその外側のクラスへの暗黙的な参照を含んでいません。

Kotlinインタフェース

図8は、インタフェースKotlinのJavaと同様である:それらは、非抽象定義と抽象メソッド実装方法を含むことができます。違いは、Java 8で、あなたは、Java 8を必要とするということであるような実装にデフォルトのキーワードをマークし、Kotlin特別なコメント:唯一のメソッド本体を提供する必要があります。例:

interface Clickable {
    fun click()
    fun showOff() { //带默认方法的实现
        println("Clickable!")
    }
}

道の基本的な定義は、インターフェイスを実装する方法の後、我々の理解は、インターフェイス上でですか?Kotlinは、代わりにJavaが延びており、キーワードを実装でのクラス名の後にコロンを使用しています。Javaのような、クラスは、任意の数のインターフェイスを実装することができますが、唯一のクラスを継承することができます。そして、Javaは、@Override 同様の注釈、Kotlin使用してoverride 修飾は、親クラスやメソッドのインターフェースのプロパティをラベル付けするために書き直されています。JavaはKotlinに使用されているとは異なりoverride 修飾子は必須です。 

open class TextView : Clickable {

    override fun click() {
        // 此方法必须实现
    }

//    override fun showOff() { //接口有默认实现,这里可以不用再实现此方法
//        super.showOff()
//    }

}

class Button : TextView() {
    // 需要注意的是,Kotlin中继承与实现接口都是用的冒号,区别在于继承类时,
    //如果父类有主构造方法,则需要在类名后添加括号及主构造函数中的参数,如果没有主构造方法,
    //则必须加上一个默认的空括号来表示。
    //如上面的TextView(),而继承接口只需要直接写接口名称即可。关于主构造函数下面有说
}

我々はFocusableのインタフェースを持っているのであれば、このインターフェイス上の1と同じクリッカブルインタフェースShowoffの方法は、最終的にこれらの2つの方法を達成するためにどのようにするときのTextViewが両方のインタフェースを継承するとき、ありますか?

open class TextView : Clickable,Focusable {

  /**
  * 如果同样的继承成员有不止一个实现,那么必须最少提供一个显示实现
  * 即super<Clickable>.showOff()
        super<Focusable>.showOff()两行中最少要调用其中一行
  */
    override fun showOff() {
      // 通过下面代码显示的实现两个showOff方法
        super<Clickable>.showOff()
        super<Focusable>.showOff()
    }
    
    override fun click() {
        // 此方法必须实现
    }
}

修飾子

開いた

Javaのは、明示的に使用しない限り、クラスのサブクラスを作成し、任意のメソッドをオーバーライドすることを可能にするfinal キーワードのタグ付けを。Kotlinでは、デフォルトではさfinal 、つまり、デフォルトでは、継承されたり上書きされていません。あなたはクラスのサブクラスを作成できるようにしたい場合は、使用する必要があるopen クラスを識別するための修飾子を。さらに、各プロパティまたはメソッドの必要性は、追加するためにオーバーライドすることができますopen 修飾子を。

注意:あなたは、基本クラスをオーバーライドするか、インターフェイスメンバーが同じデフォルトのメンバーが開いて書き直した場合。あなたの実装を書き換え、この動作を変更するクラスのサブクラスを停止したい場合は、明示的に書き換えのメンバーとして表示することができますfinal 。

open class RichButton:Clickable{ //这个类是open的,其他类可以继承它
    override fun click() {//这个函数重写了一个open函数并且它本身也是oepn的
        
    }
    fun disable(){} //这个函数是final的:不能在子类中重写它
    
    open fun animate(){} //这个函数是open的,可以在子类中重写它
}

抽象

Kotlin、Javaのと同じで、クラスは次のように宣言することができabstract 、インスタンス化することはできません。このクラスの。抽象クラスは、典型的には、いくつかは実現しなかった含まれており、抽象メンバーのサブクラスでオーバーライドする必要があります。抽象メンバーは常にで開かれ、明示的にオープン修飾子を使用する必要はありません。

abstract class Animated{ //这个类是抽象的:不能创建它的实例
    abstract fun animate()//这个函数是抽象的:他没有实现,必须被子类重写

    open fun stopAnimating(){ //抽象类中的非抽象函数并不是默认open的,但是可以标注为open的

    }

    fun animateTwice(){ // 不是open的,不能被重写

    }
}

クラスのアクセス修飾子の意味

修飾子 関連メンバー 解説
最後の それは書き換えることができません クラスメンバーのデフォルト
開いた それは書き換えることができます。 明確なショーであるために
抽象 それは書き直さなければなりません 抽象クラスにのみ使用します。抽象メンバーが実現していることができません
オーバーライド 親クラスまたはメンバーインターフェイスをオーバーライド 何の最後のショーは、メンバーのデフォルトオープンオーバーライドされていない場合

可視性修飾子(パブリックなど)

でのJava Kotlinにおける同様の可視性修飾子。また、あなたは、公共の保護やプライベート修飾子を使用することができます。しかし、デフォルトの可視性は同じではありません:あなたは修飾子を省略した場合、デフォルトでは、公共の宣言です。
デフォルトの可視性でのJava -プライベートパッケージは、でKotlinには使用されません。Kotlinネームスペースで使用されるコードを整理する方法としてではなく、その視認性制御としてのみパケット。
あるいは、Kotlinは、新しい修飾子を提供internal 示す「のみモジュール内の目に見えます。」モジュールは、一緒にコンパイルKotlinファイルのグループです。これはのIntelliJ IDEAモジュール、Eclipseプロジェクト、プロジェクトのGradleやMavenやコンパイルされたファイルのセットを使用してAntタスクの呼び出しかもしれません。

Kotlinの可視性修飾子

修飾子 クラスメンバ トップレベルの宣言
pulbic(デフォルト) すべての目に見える場所 すべての目に見える場所
内部 モジュールは、見ることができます モジュールは、見ることができます
保護されました サブクラスの目に見えます 保護されていない修飾子
プライベート 可視クラス 目に見えるファイル

例:各列の次の機能は、表示規則に違反しようとgiveSpeech。エラーはコンパイル時に発生します。

 internal open class TalkativeButton:Focusable{
        private fun yell() = println("Hey!")
        protected  fun whisper() = println("talk")
    }
    
 fun TalkativeButton.giveSpeech(){ //错误:"public"成员暴露了其"internal"接收者类型TalkativeButton
      yell() //错误:不能访问"yell()":它在"TalkativeButton"中是"private"的
     whisper() //错误:不能访问"whisper()":它在"TalkativeButton"中是"protected"的
  }

あなたがアクセスしたい場合はgiveSpeech両方が内部関数を変更し、上記の例の問題を解決するために、あなたはまた、当然のことながら、公共の種類を変更することができます「叫ぶとささやき方法、あなたは、これら2つのメソッドを読み取る必要があるパブリックまたは内部A。

内部ネストされたクラスとクラス

Javaのような、あなたはでKotlinに別のクラスでクラスを宣言することができます。違いは、あなたが特別な要求を行う場合を除きKotlinネストされたクラスは、外部クラスのインスタンスにアクセスすることはできませんです。
Kotlinでは、Javaの静的ネストされたクラス内の同じネストされたクラス修飾子で示されていません。外側のクラスへの参照を保持するために内部クラスにそれを回し、次にあなたが使用する必要がinner 修飾子を。また、異なるKotlin Java構文での外部参照クラスの例。あなたはInnerClassからOuterclassクラスを訪問し、このの@ OuterClassを使用する必要があります。

そして、Javaクラスの内部のネストしたクラスは、Kotlinに対応します

別のクラスBに宣言されたクラス、 Javaでは Kotlinで
ネストされたクラス(クラスが外部の基準に格納されていません) 静的クラスA クラスA
内部クラス(クラス外部メモリ参照) クラスA 内部クラスA

密封されたシールクラス:制限付きの継承構造を定義します。

とき式を実行するための構造を使用する場合は、Kotlinコンパイラは、デフォルトのオプションをチェック施行されます。たとえば、次のように表す数字のNum、および2つの式2つの和の合計を表します。Exprに親クラスが2つのサブクラスを持っていると仮定します。とき表現非常に便利な、確かに可能なすべてのサブクラスを扱うが、一致させることができ、他の枝の欠如に対処するため、他のブランチを提供する必要があります。

interface Expr

class Num(val value:Int):Expr
class Sum(val left:Expr,val right:Expr):Expr

fun eval(e:Expr):Int = when(e){
    is Num -> e.value
    is Sum -> eval(e.right)+ eval(e.left)
    else -> throw IllegalArgumentException("Unknown expression")
}

条件は意味のある値を返すことができないため、上記の例では、他の、直接は例外をスロー。新しいサブクラスを追加した場合、コンパイラは変更する場所を見つけることができません。新しいブランチを追加するのを忘れた場合、それは潜在的なバグにつながる可能性があり、デフォルト他の枝を選択します。
密封されたクラス:Kotlinは、この問題に対する解決策を提供します。親クラス密封された修飾子を追加し、サブクラスのセット厳しい制限を作成することができます。親クラスのすべての直接のサブクラスを入れ子にする必要があります。

sealed class Expr{
    class Num(val value:Int):Expr()
    class Sum(val left:Expr,val right:Expr):Expr()
}

fun eval(e:Expr):Int = when(e){
    is Expr.Num -> e.value
    is Expr.Sum -> eval(e.right)+ eval(e.left)
}

あなたが表現密封されたすべてのクラスのサブクラスを扱う場合は、もはやデフォルトのブランチを提供しませんでしょう。注、密封された修飾子は、このクラスはオープンクラスで、あなたはもはや明示的にオープン修飾子を追加する必要があることを意味しません。あなたは値を返す式がコンパイルに失敗したときに、時間の新しいサブクラスを追加するためのクラス(expr)はサブクラスを封印しているとき。私たちは、新しいブランチの新しいサブクラスを追加する必要があります。

ステートメントのコンストラクタ

Javaはクラス内の1つのまたは複数のコンストラクタを宣言することができます。主要構成方法の区別(クラスを初期化するために、通常、主及び簡単な方法、およびクラス宣言の外側)とコンストラクタ(体内に宣言されたクラス)から:Kotlinは、少し修正を行うための知識と同様です。

主なコンストラクタ

クラス宣言クラス名は直接ブラケットの後ろには、対応するパラメータは括弧で宣言されている宣言するときに、メインコンストラクタは典型的に添加され、それらは括弧の文ブロックのコンストラクタと呼ばれるショットで囲まれています。コードは以下の通りであります:

//以下代码即表示声明了一个带有nickname参数的主构造方法
class User(val nickname: String)

上記のコードは、コンストラクタ宣言を習得する最も簡単な方法ですが、実際には、上記のコードKotlinは最終的に、我々はそれがどのように機能するかを見に対処する私たちを助けになります。

class User constructor(_nickname: String) {
    val nickname: String

    init {
        nickname = _nickname
    }
}

上記の例では、ありましたconstructor し、init 二つの新しいキーワード。コンストラクタは、キーワードやメインのコンストラクタコンストラクタからの宣言を開始するために使用されます。キーワードを導入するためのinitはブロックを初期化します。主なコンストラクタ構文の制限なので、あなたが理由初期化ステートメントブロックを使用する理由である初期化コードを含めることはできません。あなたの理由場合は、クラス内の文の複数の初期化ブロックを宣言することができます。

それが宣言ニックネーム属性と組み合わせることができるので、もちろん、単なる代入演算子上記のコードブロックのような初期設定ステートメント場合は、次に我々は、= _nicknameブロックの初期化ステートメントのコード割り当てのこの行をニックネームを必要としない場合があります。ノー主コンストラクタまたは注釈の可視性修飾した場合、同じキーワードがコンストラクタを省略することができます。次のように最終的なコードを簡素化することができます。

class User constructor(_nickname: String) {
  val nickname = _nickname
}

これらの三つの主要なコンストラクタ文は最も簡潔な構文を使用してのみ最初、同じ方法です。

コンストラクタパラメータ宣言がデフォルト値であるような方法は、メイン関数のパラメータとして構成されてもよいです。

class User(val nickname:String = "xiaochao",val isSubscribed:Boolean = true)

fun main(args: Array<String>) {
    val user1 = User("hello")
    val user2 = User(isSubscribed = false)
    val user3 = User("kotlin",false)
}

あなたのクラスは親クラスを持っている場合は、メインのコンストラクタは、親クラスでも必要と初期化します。

open class User(val nickname: String)

class MyUser(nickname:String) :User(nickname){
    //...
}

あなたはクラスのすべてのコンストラクタを宣言しない場合、デフォルトのコンストラクタを生成します何もしないサブクラスがある場合は、クラスを継承し、それはありませんがあっても、明示的に呼び出す必要があり、クラスのデフォルトコンストラクタをサブクラス化パラメータ:

open class Button

class RadioButton: Button() {
    //...
}

あなたのクラスが他のコードをインスタンス化されていないことを確認したい場合は、コンストラクタをマークする必要がありますprivate 。

class User private constructor(val name:String){
    //...
}

コンストラクタから

我々上記のクラスは、任意のコンストラクタの時間を定義していないとき、サブクラスにクラスが常にデフォルトコンストラクタは、親クラスのディスプレイを呼び出す必要が継承するので、Kotlinは自動的に、デフォルトのメインコンストラクタを生成することを述べました。場合は、クラスのコンストラクタは以下から定義されているが、主な施工方法は、それが自動的にメインを生成するために、そのデフォルトコンストラクタをKotlinていない場合に定義されていない場合。サブクラスからスーパークラスのコンストラクタは、表示したい時間を継承します呼び出します。コードは以下の通りであります:

open class User{
    constructor(userName:String){
        //...
    }
    constructor(userName: String,age:Int){
        //...
    }
}

class MyUser:User{
    constructor(userName:String):super(userName) // 调用父类的从构造方法
    constructor(userName: String,age:Int):super(userName,age) // 调用父类的从构造方法
}

//当然,这里也可以像之前一样通过在继承的时候就显示调用父类的从构造方法,如下
//class MyUser(userName: String) : User(userName) {
//  
//}

以上のことから、我々はそれは、サブクラス内のスーパー()キーワードを使用して、親クラスのコンストラクタの対応を呼び出して見ることができます。同時に、それは、Javaのように、この()キーワードを使用することによって、あなたはクラスのコンストラクタから別のコンストラクタを呼び出す、のようにすることができます。コードは以下の通りであります:

class MyUser : User {
    //通过this调用自己的两个参数的构造方法
    constructor(userName: String) : this(userName, 0)
    
    constructor(userName: String, age: Int) : super(userName, age)
}

サポートゲッターやセッターフィールド(フィールド)にアクセスすることにより、

class User(val name:String){
    var address: String = "unspecified"
        set(value) {
            println("$field --->${value.trimIndent()}")
            field = value
        }
}

fun main(args: Array<String>) {
    val user = User("xiaochao")
    user.address = "shanghai"
    user.address = "beijing"
}
>>> unspecified --->shanghai
>>> shanghai --->beijing

上記のコードでは、値が格納され、アクセスされ変更された属性値に追加ロジックを提供することが実現します。このケースをサポートするために、我々は、プロパティアクセサからの支援フィールド(フィールド)にアクセスできるようにする必要があります。フィールドサポートの値にアクセスするための特別な識別子フィールドを使用して、関数本体でセッター。ゲッターでは、あなただけの値を読み取ることができ、読み、それはまたそれを変更することができ、両方でセッターインチ

そこフィールドをサポートするために、何のプロパティがありませんとの違いは何ですか?
プロパティにアクセスする方法は、それがサポートフィールドが含まれているかどうかに依存しません。あなたが明示的に参照するか、デフォルトのアクセスが実装されている使用している場合は、コンパイラがサポートフィールドがプロパティですが生成されます。カスタムアクセサの実装を提供し、使用しない場合はfield 、サポートフィールドが提示されることはありません。

デフォルトのアクセス制御の実装を変更しますが、その可視性を変更する必要がありますすることが時々必要。次のサンプルコード:

class LengthCounter {
    var counter: Int = 0
        private set

    fun addWord(word: String) {
        counter += word.length
    }
}

fun main(args: Array<String>) {
    val lengthCounter = LengthCounter()
    lengthCounter.addWord("HelloWorld!")
    println(lengthCounter.counter)
}

>>> 11

データクラスのデータ

有するデータクラスdata キーワード修飾クラスは、データがKotlinクラスが等しい書き換えられたハッシュコード、toStringメソッドを表します。例としては、次のとおりです:

class Student(val name:String,val age:Int)

data class DataStudent(val name:String ,val age:Int)

fun main(args: Array<String>) {
    val xiaoming1 = Student("xiaoming",20)
    val xiaoming2 = Student("xiaoming",20)
    val xiaomingSet = hashSetOf(xiaoming1,xiaoming2)
    println(xiaoming1.toString())
    println(xiaoming1==xiaoming2)
    println("size = ${xiaomingSet.size} ${xiaomingSet.contains(Student("xiaoming",20))}")
    println("----------------------------")

    val dataxiaoming1 = DataStudent("xiaoming",20)
    val dataxiaoming2 = DataStudent("xiaoming",20)
    val dataxiaomingSet = hashSetOf(dataxiaoming1,dataxiaoming2)
    println(dataxiaoming1.toString())
    println(dataxiaoming1==dataxiaoming2)
    println("size = ${dataxiaomingSet.size} ${dataxiaomingSet.contains(DataStudent("xiaoming",20))}")
}

>>>chapter04.Student@3fee733d
>>>false
>>>size = 2 false
>>>----------------------------
>>>DataStudent(name=xiaoming, age=20)
>>>true
>>>size = 1 true

そして、不変データクラス:コピー()メソッド

データクラス属性はヴァルである必要はありませんが - もVARを使用することができます - 強くなるようにサンプルデータクラス不変、唯一のval属性を使用することをお勧めします。あなたがいない場合、オブジェクトは容器に添加された後の主な変更として使用されているので、必須要件であるHashMapのキーまたは類似の容器、などの例を使用したい場合は、容器を無効状態に入ることがあり。オブジェクトが作成されると、それはあなたのコードは、他のスレッドがオブジェクトの値を変更したときに動作します心配しないで、初期状態のままになります:不変オブジェクトは、特にマルチスレッドで、理解するのも簡単です。

簡単不変データオブジェクトクラスで利用する複数のメソッドを生成し、Kotlinコンパイラする:クラスの一例は、コピーを許可し、コピーしながら、特定のプロパティの値を変更します。変形例のコピーを作成することは、通常は良い選択です:ライフサイクルの別のコピーを持っており、コードの位置には影響を与えませんが、元のインスタンスを参照します。ここでの方法は、手動で実装されるようになりますコピーします。

class Student(val name:String,val age:Int){
    fun copy(name:String = this.name,age:Int = this.age) = Student(name,age)
}

fun main(args: Array<String>) {
    val student = Student("xiaoming",22)
    println(student.copy(age = 23).age)
}
>>> 23

これは、データ修飾子は値オブジェクトクラスで、より便利な理由を使用する方法です。

クラスのデリゲート:キーワードで

開発では、私たちはしばしば、それが拡張できるように設計されていなかったにもかかわらず、他のクラスにいくつかの動作を追加する必要があるかもしれません。一般的な実装は、装飾モードで有名です。このモデルの本質は、オリジナルとフィールドとして保存するためのクラスインターフェイスの元のインスタンスと同じクラスを実装する新しいクラスを作成することです。方法が変更されずに、元のクラスと同じ振る舞いを持っている、あなただけが元のクラスのインスタンスに直接転送する必要があります。

このアプローチの一つの欠点は、定型コードのかなりの量が必要です。たとえば、ここにあなたが行為のいずれかを変更する必要がない場合でも、装飾などのコレクションから取得するためのシンプルなインターフェイスを実装する必要がどのくらいのコードです:

class DelegatingCollection<T> : Collection<T> {
    private val innerList = arrayListOf<T>()
    override val size: Int
        get() = innerList.size

    override fun contains(element: T): Boolean = innerList.contains(element)

    override fun containsAll(elements: Collection<T>): Boolean = innerList.containsAll(elements)

    override fun isEmpty(): Boolean = innerList.isEmpty()

    override fun iterator(): Iterator<T> = innerList.iterator()
}

Kotlinは、インターフェイスを実装するたびに、あなたが使用することができ、ファーストクラスのサポートを行うための機能の言語レベルとして委嘱されby 、別のオブジェクトへのインターフェイスの実装を委任するためのキーワードを。次のキーワードによって、同じ機能のコードを使用することにより上記目的を達成するために:

class DelegatingCollection<T>(innerList: Collection<T> = ArrayList<T>())
    : Collection<T> by innerList

あなたが特定のメソッドの動作を変更する必要がある場合さて、あなたはあなたの方法ではなく、生成方法を使用すると呼ばれるように、それらを書き換えることができます。あなたは、内部実装の既定のインスタンスに満足デリゲートを保持することができます。

class CountingSet<T>(val innerList: MutableCollection<T> = HashSet<T>()) : MutableCollection<T> by innerList {
    var objectsAdd = 0
    override fun add(element: T): Boolean {
        objectsAdd++
        return innerList.add(element)
    }

    override fun addAll(elements: Collection<T>): Boolean {
        objectsAdd += elements.size
        return innerList.addAll(elements)
    }
}

fun main(args: Array<String>) {
    val cset = CountingSet<Int>()
    cset.addAll(listOf(1, 2, 2))
    println("${cset.objectsAdd}     ${cset.size}")
}

>>> 3     2

オブジェクト:クラスを宣言し、インスタンスの組み合わせを作成します

object 三つの主要なシナリオがありますキーワードを使用します。

  • 定義されたシングルトン
  • 代替Javaの匿名内部クラス
  • コンパニオンに関連付けられたオブジェクトを作成します

オブジェクトの宣言:オブジェクトによってシングルトンを作成します

object SingleInstance {
    var name: String? = null
    fun initName() {
        name = "hello world"
    }
}

fun main(args: Array<String>) {
    val a = SingleInstance
    val b = SingleInstance
    SingleInstance.initName()
    b.initName()
    println(a === b)
}
>>> true

そしてクラスは、オブジェクトの宣言文は、属性、メソッド、およびその他の初期化ステートメントのブロックが含まれていてもよいです。建設の唯一の方法は、(からメソッドやコンストラクタのための主要な構成を含む)を許可されません。そして、異なるオブジェクトの共通サンプルがすぐに作成定義された時に宣言しました。同じ文では、オブジェクトクラスとインタフェースから継承することができます。

対象と代替Javaの匿名内部クラス

interface Click{
    fun onClick()
    fun onLongClick()
}

fun main(args: Array<String>) {
    val clickClistener = object :Click{
        override fun onClick() {
        }

        override fun onLongClick() {
        }
    }
}

異なるオブジェクトの宣言と、匿名の内部クラスを表すためにオブジェクトを使用する場合、匿名オブジェクトは、単一の例ではない、式オブジェクトが新しいオブジェクトのインスタンスを作成するたびに実行されます。

関連するオブジェクト

Kotlinはクラスの静的メンバを持つことはできません。Javaでstaticキーワードの一部はKotlin言語ではありません。別の方法として、Kotlinは、パッケージレベルの関数やオブジェクトの宣言を依存している、ほとんどの場合、トップレベルの機能を使用することをお勧めしますが、トップレベルの関数のクラスのprivateメンバーにアクセスすることはできません。この時間は、それはコンパニオンオブジェクトによってこの問題を解決することを検討することができます。Kotlin、関連付けられてオブジェクトにcompanion マーク。構文は次のとおりです。

class A {
    companion object {
        const val name = "Hello world"
        fun bar() {
            println("Companion object called")
        }
    }
}

fun main(args: Array<String>) {
    A.bar()
    A.name
}

コンパニオンオブジェクトは、共通のオブジェクトがクラス内で宣言され、それは名前を持っている、またはインターフェイスが機能またはプロパティを広がっている実装することができます。

interface Click{   
        fun onClick()
    fun onLongClick()
}

class A {
    companion object Inner : Click { // 实现接口
        override fun onClick() {
        }

        override fun onLongClick() {
        }

        const val name = "Hello world"
        fun bar() {
            println("Companion object called")
        }
    }
}

fun A.Inner.kuozhan() { //扩展函数
    println("这是伴生对象的扩展函数")
}

fun main(args: Array<String>) {
    A.bar()
    A.name
    A.Inner.bar()
    A.Inner.name
    A.Inner.kuozhan()
}

概要

  1. Kotlinのインターフェースは、Javaに似ていますが、デフォルトの実装および属性を(Javaは第8版をサポートするために始めた)を含有してもよいです。
  2. すべてのステートメントは、デフォルトであるfinal とpublic 。
  3. 宣言がないようにするにはfinal 、およびとしてそれをマークopen 。
  4. internal 同じモジュールで見られる声明。
  5. デフォルトでは、クラス内の入れ子になったクラスではありません。使用するinner 外部ストレージに内部クラス、クラス参照を宣言するためのキーワードを。
  6. sealed クラスのサブクラスは、独自の文の中でネストすることができます(Kotlin1.1同じファイルのどこにでも配置サブクラスを許可します)。
  7. クラスのインスタンスの初期化方法からの初期ブロックおよび構成は、柔軟性を提供します。
  8. 使用するfield 参照フィールドに識別子をサポートアクセスメソッド本体容器を属性。
  9. クラスは、コンパイラ等しい、ハッシュコード、のtoString、コピー、および他の方法によって生成されたデータを提供します。
  10. 多くの同様のクラスのデリゲートデリゲートメソッドがコードで表示されないように役立ちます。
  11. メソッドオブジェクトの宣言は、単一の実施形態Kotlinクラスで定義されています。
  12. コンパニオン・オブジェクト(一緒にパッケージレベルの関数との結合性)は、Java静的メソッドとフィールドを置き換えます。
  13. 他のオブジェクトに関連付けられているオブジェクトは、あなたは、インターフェイスを実装することができ、それはまた、拡張機能や特性を有することができます。
  14. オブジェクト式は、Javaの匿名内部クラスでの選択肢をKotlinであり、そのような複数のインターフェースやその他の機能を実装する機能など、ドメイン内のオブジェクトの役割で定義された変数を変更して作成する機能が追加されます。

おすすめ

転載: www.cnblogs.com/xxiaochao/p/11497252.html