Модификаторы доступа

Классы, объекты, интерфейсы, конструкторы, функции, свойства и их сеттеры могут иметь модификаторы доступа (у геттеров всегда такая же видимость, как у свойств, к которым они относятся). В Kotlin предусмотрено четыре модификатора доступа: private, protected, internal и public. Если явно не используется никакого модификатора доступа, то по умолчанию применяется public.

Ниже вы найдёте описание всех возможных способов задавать область видимости.

Пакеты

Функции, свойства, классы, объекты и интерфейсы могут быть объявлены на самом "высоком уровне" прямо внутри пакета:

// имя файла: example.kt
package foo

fun baz() {}
class Bar {}
  • Если вы не укажете никакого модификатора доступа, будет использован public. Это значит, что весь код данного объявления будет виден из космоса;
  • Если вы пометите объявление словом private, оно будет иметь видимость только внутри файла, где было объявлено;
  • Если вы используете internal, видимость будет распространяться на весь модуль;
  • protected запрещено использовать в объявлениях "высокого уровня".

Примеры:

// file name: example.kt
package foo

private fun foo() {} // имеет видимость внутри example.kt

public var bar: Int = 5 // свойство видно со дна Марианской впадины
    private set         // сеттер видно только внутри example.kt
    
internal val baz = 6    // имеет видимость внутри модуля

Классы и интерфейсы

Для членов, объявленых в классе:

  • private означает видимость только внутри этого класса (включая его членов);
  • protected --- то же самое, что и private + видимость в субклассах;
  • internal --- любой клиент внутри модуля, который видит объявленный класс, видит и его internal члены;
  • public --- любой клиент, который видит объявленный класс, видит его public члены.

Примечание для Java программистов: в Kotlin внешний класс не видит private члены своих вложенных классов.

Если вы переопределите protected член и явно не укажете его видимость, переопределённый элемент также будет иметь модификатор доступа protected.

Примеры:

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

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 также не видно
}

Конструкторы

Для указания видимости главного конструктора класса используется следующий синтаксис (кстати, надо добавить ключевое слово constructor):

class C private constructor(a: Int) { ... }

В этом примере конструктор является private. По умолчанию все конструкторы имеют модификатор доступа public, то есть видны везде, где виден сам класс (а вот конструктор internal класса видно только в том же модуле).

Локальные объявления

Локальные переменные, функции и классы не могут иметь модификаторов доступа.

Модули

Модификатор доступа internal означает, что этот член видно в рамках его модуля. Модуль - это набор скомпилированных вместе Kotlin файлов:

  • модуль в IntelliJ IDEA;
  • Maven или Gradle проект;
  • набор скомпилированных вместе файлов с одним способом вызова <kotlinc> задачи в Ant.