本片博客会很简单的阐述可见性修饰符
1. kotlin总共有四个修饰符:private 、protected 、internal 和 public。
2. 四个修饰符能修饰:类、对象、接⼝、构造函数、⽅法、属性和它们的 setter 都可以有 可⻅性修饰符。
3. 要注意的是:getter访问器的可见性一定是与属性一样的,所以我们要改变访问器的可见性只能改变setter。
4. 如果没有显式指定修饰符的话,默认可⻅性是 public。
5. 不同的作用域,这些修饰符修饰的可见性是不一样的
包中的可见性(所谓的顶层)
函数、属性和类、对象和接⼝可以在顶层声明,即直接在包内。
1. 如果你不指定任何可⻅性修饰符,默认为 public ,这意味着你的声明将随处可⻅。
2. 如果你声明为 private ,它只会在声明它的⽂件内可⻅。
3. 如果你声明为 internal ,它会在相同模块内随处可⻅。
4. protected 不适⽤于顶层声明,一般只会出现在类中。
这里有必要解释什么是模块
模块
可⻅性修饰符 internal 意味着该成员只在相同模块内可⻅。更具体地说,⼀个模块是编译在⼀起的⼀套 Kotlin ⽂件:
⼀个 IntelliJ IDEA 模块;
⼀个 Maven 项⽬;
⼀个 Gradle 源集;
⼀次 <kotlinc> Ant 任务执⾏所编译的⼀套⽂件。
像如下的代码:
// ⽂件名:example.kt
package foo
private fun foo() {} // 在 example.kt 内可⻅
public var bar: Int = 5 // 该属性随处可⻅
private set // setter 只在 example.kt 内可⻅
internal val baz = 6 // 相同模块内可⻅
类和接⼝
1. private 意味着只在这个类内部(包含其所有成员)可⻅;
2. protected ⸺ 和 private ⼀样 + 在⼦类中可⻅。
3. internal ⸺ 能⻅到类声明的 本模块内 的任何客⼾端都可⻅其 internal 成员;
4. public ⸺ 能⻅到类声明的任何客⼾端都可⻅其 public 成员。
注意 对于Java⽤⼾:Kotlin 中外部类不能访问内部类的 private 成员。
如果你覆盖⼀个 protected 成员并且没有显式指定其可⻅性,该成员还会是 protected 可⻅性。
同时要注意的是,和Java不同的是,protected修饰,Java里是希望子类覆盖的,但是Kotlin只是增加子类的访问性,并没有希望覆盖。要使成员被覆盖还是要open
例⼦:
open class Outer {
private val a = 1
protected open val b = 2
internal val c = 3
val d = 4 // 默认 public
protected class Nested {
public val e: Int = 5 //一般public都不需要用public修饰,默认就好,减少代码量
fun getA() = Outer().a
}
class B{
fun getA() = Outer().a
}
inner class C {
private var i = 1
fun getA() = this@Outer.a //内部类能访问外部内的任何成员
}
//fun getI() = this.C().i //外部类不能访问内部类的私有成员
}
class Subclass : Outer() {
// a 不可⻅
// b、c、d 可⻅
// Nested 和 e 可⻅
override val b = 5 // “b”为 protected
}
class Unrelated(o: Outer) {
// o.a、o.b 不可⻅
// o.c 和 o.d 可⻅(相同模块)
// Outer.Nested 不可⻅,Nested::e 也不可⻅
}
fun main(args: Array<String>) {
//var n = Outer.Nested() //Nested只能被Outer的子类可见
//var a = Outer().a //只有Outer内部有可见性,包括了嵌套类
var a = Outer.B().getA() //私有的可以通过开放的接口获得,和Java一样
}
构造函数
要指定⼀个类的的主构造函数的可⻅性,使⽤以下语法(注意你需要添加⼀个显式 constructor 关键字)
class C private constructor(a: Int)
一般私有化构造方法是为了不让外部随意的创建对象,如Java的单例模式。
函数(局部声明)
在函数中不能使用可见性修饰符