扔物线Kotlin讲解学习(一)----Kotlin的权限修饰符详解

Kotlin 中有四种可见性修饰符:
public:公开,可见性最大,哪里都可以引用。
private:私有,可见性最小,根据声明位置不同可分为类中可见和文件中可见。
protected:保护,相当于 private + 子类可见。
internal:内部,仅对 module 内可见。

相比 Java 少了一个 default 「包内可见」修饰符,多了一个 internal「module 内可见」修饰符。
public
Java 中没写可见性修饰符时,表示包内可见,只有在同一个 package 内可以引用:

package org.kotlinmaster.library; 
// 没有可见性修饰符
class User {
}
                      // 👇 和上面同一个 package
package org.kotlinmaster.library;

public class Example {
    void method() {
        new User(); // success
    }
}

package org.kotlinmaster;
                    // 👆 和上面不是一个 package
import org.kotlinmaster.library.User;
                          👆
public class OtherPackageExample {
    void method() {
        new User(); // compile-error: 'org.kotlinmaster.library.User' is not public in 'org.kotlinmaster.library'. Cannot be accessed from outside package
    }
}

package 外如果要引用,需要在 class 前加上可见性修饰符 public 表示公开。
Kotlin 中如果不写可见性修饰符,就表示公开,和 Java 中 public 修饰符具有相同效果。在 Kotlin 中 public 修饰符「可以加,但没必要」。

@hide

在 Android 的官方 sdk 中,有一些方法只想对 sdk 内可见,不想开放给用户使用(因为这些方法不太稳定,在后续版本中很有可能会修改或删掉)。为了实现这个特性,会在方法的注释中添加一个 Javadoc 方法 @hide,用来限制客户端访问:

/**
* @hide 👈
*/
public void hideMethod() {
    ...
}

但这种限制不太严格,可以通过反射访问到限制的方法。针对这个情况,Kotlin 引进了一个更为严格的可见性修饰符:internal。

internal

internal 表示修饰的类、函数仅对 module 内可见,这里的 module 具体指的是一组共同编译的 kotlin 文件,常见的形式有:

Android Studio 里的 module
Maven project
我们常见的是 Android Studio 中的 module 这种情况,Maven project 仅作了解就好,不用细究。

internal 在写一个 library module 时非常有用,当需要创建一个函数仅开放给 module 内部使用,不想对 library 的使用者可见,这时就应该用 internal 可见性修饰符。

Java 的「包内可见」怎么没了?
Java 的 default「包内可见」在 Kotlin 中被弃用掉了,Kotlin 中与它最接近的可见性修饰符是 internal「module 内可见」。为什么会弃用掉包内可见呢?我觉得有这几个原因:

Kotlin 鼓励创建 top-level 函数和属性,一个源码文件可以包含多个类,使得 Kotlin 的源码结构更加扁平化,包结构不再像 Java 中那么重要。
为了代码的解耦和可维护性,module 越来越多、越来越小,使得 internal 「module 内可见」已经可以满足对于代码封装的需求。
protected
Java 中 protected 表示包内可见 + 子类可见。
Kotlin 中 protected 表示 private + 子类可见。
Kotlin 相比 Java protected 的可见范围收窄了,原因是 Kotlin 中不再有「包内可见」的概念了,相比 Java 的可见性着眼于 package,Kotlin 更关心的是 module。

private
Java 中的 private 表示类中可见,作为内部类时对外部类「可见」。
Kotlin 中的 private 表示类中或所在文件内可见,作为内部类时对外部类「不可见」。
private 修饰的变量「类中可见」和 「文件中可见」:

class Sample {
    private val propertyInClass = 1 // 👈 仅 Sample 类中可见
}

private val propertyInFile = "A string." // 👈 范围更大,整个文件可见

private 修饰内部类的变量时,在 Java 和 Kotlin 中的区别:

在 Java 中,外部类可以访问内部类的 private 变量:

public class Outter {
    public void method() {
        Inner inner = new Inner();
                            👇
        int result = inner.number * 2; // success
    }
    
    private class Inner {
        private int number = 0;
    }
}

在 Kotlin 中,外部类不可以访问内部类的 private 变量:

class Outter {
    fun method() {
        val inner = Inner()
                            👇
        val result = inner.number * 2 // compile-error: Cannot access 'number': it is private in 'Inner'
    }
    
    class Inner {
        private val number = 1
    }
}

可以修饰类和接口

Java 中一个文件只允许一个外部类,所以 class 和 interface 不允许设置为 private,因为声明 private 后无法被外部使用,这样就没有意义了。

Kotlin 允许同一个文件声明多个 class 和 top-level 的函数和属性,所以 Kotlin 中允许类和接口声明为 private,因为同个文件中的其它成员可以访问:

private class Sample {
    val number = 1
    fun method() {
        println("Sample method()")
    }
}
            // 👇 在同一个文件中,所以可以访问
val sample = Sample()

版权声明
本文首发于:https://rengwuxian.com/kotlin-basic-2/
微信公众号:扔物线
转载时请保留此声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值