天天看點

Kotlin學習筆記——可見性修飾符包内頂層聲明的通路修飾符類和接口中聲明的修飾符為構造函數添加通路修飾

    在

Kotlin

中,類、對象、接口、構造函數、方法、屬性和它們的

setter

都可以有 可見性修飾符。 (

getter

總是與屬性有着相同的可見性。) 在

Kotli

n 中有這四個可見性修飾符:

private

protected

internal

public

。 如果沒有顯式指定修飾符的話,預設可見性是

public

包内頂層聲明的通路修飾符

可以在函數、屬性和類、對象和接口頂層聲明,即直接在包内聲明

package com.xiaoying.base
fun main(args: Array<String>) {
    
}

// 隻在檔案内可見
private fun test() {
}

class Base {
}
           

頂層聲明的通路修飾符有以下特點

  • 如果你不指定任何可見性修飾符,預設為

    public

    ,這意味着你的聲明将随處可見;
  • 如果你聲明為

    private

    ,它隻會在聲明它的檔案内可見(如果類内部的);
  • 如果你聲明為

    internal

    ,它會在相同子產品内随處可見;
  • protected

    不适用于頂層聲明。
  • 一個檔案隻能有一個包聲明。
  • 雖然

    public

    修飾符随處可見,但是在不同的包進行引用時,必須導入包。

類和接口中聲明的修飾符

對于類内部聲明的成員:

  • private

    隻在這個類内部(包含類所有成員)可見;
  • protected

    在這個類的内部極其子類中可見(如果覆寫一個 protected 成員并且沒有顯式指定其可見性,該成員還會是 protected 可見性);
  • internal

    隻在能見到類聲明的本子產品内可見;
  • public

    在能見到類聲明的任何地方都可見這個類的

    public

    成員。
注意: 跟Java不同的是,Kotlin中外部類不能通路内部類的 private 成員。
open class A {

    // 沒有指定預設public
    open fun printTest() {
        test()

        val b = B()
        b.printTest() // public的成員,隻要能看見類聲明的地方都可以通路

//        b.test() B類中的private成員,隻能在B内部通路,外部無法通路
    }

    private fun test() {
        println("This is test in A")
    }

    protected open fun play() {
        println("Play in A")
    }

    internal fun stopPlay() {
        println("Stop play in A")
    }
}


class B {
    fun printTest() {
        test()
    }

    private fun test() {
        println("This is test in B")
    }
}

class C: A() {

    // 重寫父類的protected成員,沒有指定通路修飾,預設是protected
    override fun printTest() {
        val d = D()
        d.printTest() // 内部類的public成員可以通路
        // d.test() // 内部類的private成員不可通路,這是跟java的不同之處
    }

    fun superPlay() {
        // 父類protected的成員,在子類中可以通路
        super.play()
    }

    override fun play() {
        println("Play in C")
    }
    
    class D {
        fun printTest() {
            test()
        }
        
        // 内部類的private成員,外部類無法通路
        private fun test() {
            println("This is test in D")
        }
    }
}
           

為構造函數添加通路修飾

    預設情況下,構造函數都是

public

的。

注意:如果主構造函數修改了預設的(

public

)通路修飾符,則需要顯式使用

constructor

關鍵字
// 主構造函數如果修改預設的修飾符,需要添加constructor關鍵字
class B private constructor(var id: String) {
    
    private constructor(id: String, name: String): this(id) {
        
    }
    
    fun printTest() {
        test()
    }

    private fun test() {
        println("This is test in B")
    }
}
           

繼續閱讀