Найти тему

Модификаторы видимости в Kotlin

Оглавление

1. Введение

Язык программирования Kotlin построен на виртуальной машине Java (JVM). Как таковой, он должен следовать всем правилам, которые устанавливает JVM, включая модификаторы видимости.

Однако есть некоторые тонкие нюансы в том, как язык реализует эти модификаторы в отношении компилятора и способа структурирования нашего кода. В этой статье будут показаны некоторые сходства и различия между Java и Kotlin в этом отношении.

2. Модификаторы видимости

Модификаторы видимости используются для определения того, какие другие элементы кода имеют доступ к изменяемому элементу. Они применяются к некоторым различным элементам кода на разных уровнях области видимости. Способ применения этих правил может незначительно отличаться в зависимости от этих различных применений, что поначалу может сбивать с толку.

2.1. Публичная известность

Наиболее очевидным модификатором является public. Возможно, он наиболее часто используется во всем языке и означает, что нет никаких дополнительных ограничений на то, кто может видеть изменяемый элемент.

В отличие от Java, в Kotlin почти никогда нет необходимости объявлять что–либо как public - это модификатор по умолчанию, используемый, если мы не объявляем другой. Кроме этого, в Kotlin он работает так же, как и в Java.

Если мы применим модификатор public к элементу верхнего уровня - внешнему классу, функции или переменной, объявленным непосредственно внутри пакета, – тогда любой другой код сможет получить к нему доступ. Если мы применим модификатор public к вложенному элементу – внутреннему классу, функции или переменной внутри класса, – то любой код, который может получить доступ к контейнеру, также может получить доступ к этому элементу.

Например:

class Public {
val i = 1

fun doSomething() {
}
}

Класс Public доступен из любой точки всей кодовой базы, “val i” и “fun doSomething()” доступны из всего, что может получить доступ к Public.

2.2. Личная видимость

Другой модификатор, который используется большую часть времени, - private. Это имеет почти прямо противоположное значение public – это означает, что никто не может получить к нему доступ.

На самом деле, в Kotlin это означает, что только код, объявленный внутри той же области, может получить к нему доступ. Это немного отличается от Java просто потому, что Kotlin допускает несколько объявлений верхнего уровня в одном файле - к частному элементу верхнего уровня может быть доступно все остальное в том же файле. В остальном правила те же. Например:

Например:

private class Private {
private val i = 1

private val doSomething() {
}
}

Класс Private доступен только из того же исходного файла, “val i” и “fun doSomething()” доступны только изнутри класса Private.

2.3. Защищенная видимость

Модификатор protected в Kotlin означает, что он строго доступен только объявляющему классу и подклассам. Это то же самое, что большинство людей ожидают от Java, но слегка отличается от того, как работает Java.

В Java модификатор protected также разрешает доступ к элементу из чего-либо еще в том же пакете. Например, учитывая следующий файл класса:

package one;

class A {
protected val i = 1
}

Следующий файл будет нормально работать в Kotlin:

package two;

class B : A() {
fun getValue() : Int {
return i
}
}

Следующий файл будет работать в Java, но не будет работать в Kotlin:

package one;

class C {
fun getValue() : Int {
val a = A()
return a.i
}
}

И следующее не сработало бы ни на Java, ни на Kotlin:

package two;

class D {
fun getValue() : Int {
val a = A()
return a.i
}
}

Кроме того, в Kotlin protected становится видимостью по умолчанию, когда мы переопределяем защищенный элемент из суперкласса. При желании это может быть явно изменено на public, и это основной случай, когда нам нужно будет явно объявить что-либо как public.

2.4. Пакет-Приватный / Видимость по умолчанию

В Java существует модификатор доступа, известный как “package-private” (также называемый “default”). Это используется, когда для элемента не установлен модификатор. Это означает, что любой код в том же пакете может получить к нему доступ, но любой код в другом пакете не может, включая подклассы.

В настоящее время Kotlin вообще не поддерживает этот модификатор, хотя это может измениться в будущем. Причина этого заключается в том, что он не обеспечивает никакой защиты – любой может определить код в том же пакете и получить доступ к нашим элементам даже из другого jar-файла.

2.5. Внутренняя видимость

Kotlin добавляет новый модификатор к параметрам, которые Java в настоящее время не поддерживает – internal. Этот модификатор означает, что любой код, объявленный в том же модуле, который не ограничен иным образом, может получить доступ к этому элементу. (Модуль - это, по сути, Jar-файл.)

Это возможно в Java с использованием таких вещей, как OSGi, но в настоящее время это не является родным для языка. В Java 9 будут представлены некоторые концепции, которые сделают это более достижимым за счет возможности выборочного экспорта общедоступных идентификаторов.

Это дает огромное преимущество при написании API и реализаций. Мы можем писать наши интерфейсы API как общедоступные, нашу основную реализацию как общедоступные классы, а весь вспомогательный код, от которого он зависит, как внутренний. Это означает, что внешний код вынужден проходить через API и не может получить доступ к внутренним компонентам.

Например:

package com.baeldung.modifiers

internal class Internal {
}

class Public {
internal val i = 1

internal fun doSomething() {
}
}

Класс Internal доступен только изнутри того же модуля. “val i” и “fun doSomething()” также доступны только изнутри того же модуля, хотя к классу, внутри которого они находятся, можно получить доступ откуда угодно.

3. Завершение

В большинстве случаев правила использования модификаторов видимости в Kotlin работают так же, как мы ожидали бы от Java. Однако есть существенное отличие, которое заключается во введении внутренней области видимости, что очень полезно для более крупных проектов.

Оригинал статьи: https://www.baeldung.com/kotlin/visibility-modifiers