Modificatori di visibilità in Kotlin

1. Introduzione

Il linguaggio di programmazione Kotlin è basato sulla Java Virtual Machine (JVM). In quanto tale, deve seguire tutte le regole che la JVM impone, inclusi i modificatori di visibilità.

Tuttavia, ci sono alcune sottili sfumature nel modo in cui il linguaggio implementa questi modificatori per quanto riguarda il compilatore e il modo in cui è strutturato il nostro codice. Questo articolo mostrerà alcune delle somiglianze e delle differenze tra Java e Kotlin a questo proposito.

2. Modificatori di visibilità

I modificatori di visibilità vengono utilizzati per determinare quali altri elementi di codice hanno accesso all'elemento da modificare. Si applicano ad alcuni elementi diversi nel codice, a vari livelli di ambito. Il modo in cui queste regole vengono applicate può variare leggermente tra questi diversi usi, il che può creare confusione all'inizio.

2.1. Visibilità pubblica

Il modificatore più ovvio è pubblico . Questo è probabilmente il più utilizzato in tutta la lingua e significa che non ci sono ulteriori restrizioni su chi può vedere l'elemento modificato.

A differenza di Java, in Kotlin non è quasi mai necessario dichiarare qualcosa come pubblico : è il modificatore predefinito utilizzato se non ne dichiariamo un altro. Oltre a questo, funziona allo stesso modo in Kotlin come in Java.

Se applichiamo il modificatore pubblico a un elemento di primo livello - una classe esterna o una funzione o variabile dichiarata direttamente all'interno di un pacchetto - allora qualsiasi altro codice può accedervi. Se applichiamo il modificatore public a un elemento annidato, una classe interna o una funzione o una variabile all'interno di una classe, anche qualsiasi codice che può accedere al contenitore può accedere a questo elemento.

Per esempio:

class Public { val i = 1 fun doSomething() { } } 

Class Public è accessibile da qualsiasi punto dell'intera codebase, "val i" e "fun doSomething ()" sono accessibili da tutto ciò che può accedere a Public.

2.2. Visibilità privata

L'altro modificatore che viene utilizzato la maggior parte delle volte è privato . Questo ha quasi il significato esatto opposto di pubblico : significa che nessuno può accedervi.

In realtà, in Kotlin significa che solo il codice dichiarato all'interno dello stesso scope può accedervi . Questo è leggermente diverso da Java semplicemente perché Kotlin consente più dichiarazioni di primo livello nello stesso file: un elemento privato di primo livello è accessibile da qualsiasi altra cosa nello stesso file. A parte questo, le regole sono le stesse. Per esempio:

Per esempio:

private class Private { private val i = 1 private val doSomething() { } }

Class Private è accessibile solo dall'interno dello stesso file sorgente, "val i" e "fun doSomething ()" sono accessibili solo dall'interno della classe Private .

2.3. Visibilità protetta

Il modificatore p rotected in Kotlin significa che è strettamente accessibile solo dalla classe dichiarante e dalle sottoclassi . È lo stesso che la maggior parte delle persone si aspetta che Java funzioni, ma leggermente diverso da come funziona Java.

In Java, il modificatore protetto consente anche l'accesso all'elemento da qualsiasi altra cosa nello stesso pacchetto. Ad esempio, dato il seguente file di classe:

class A { protected val i = 1 }

Il seguente file funzionerebbe bene in Kotlin:

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

Il seguente file funzionerà in Java ma non funzionerà in Kotlin:

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

E quanto segue non funzionerebbe né in Java né in Kotlin:

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

Inoltre, in Kotlin protected diventa la visibilità predefinita quando sovrascriviamo un elemento protetto da una superclasse . Questo può essere cambiato esplicitamente in pubblico se lo si desidera ed è il momento principale in cui avremo bisogno di dichiarare qualcosa come pubblico esplicitamente.

2.4. Visibilità privata del pacchetto / predefinita

In Java, esiste un modificatore di accesso noto come "pacchetto privato" (indicato anche come "predefinito"). Viene utilizzato quando nessun modificatore è posizionato sull'elemento. Ciò significa che qualsiasi codice nello stesso pacchetto può accedervi, ma qualsiasi codice in un pacchetto diverso non può, comprese le sottoclassi.

Kotlin attualmente non ha alcun supporto per questo modificatore , anche se questo potrebbe cambiare in futuro. La ragione di ciò è che non offre alcuna protezione: chiunque può definire il codice nello stesso pacchetto e accedere ai nostri elementi, anche da un file jar diverso.

2.5. Visibilità interna

Kotlin aggiunge un nuovo modificatore alle opzioni che Java attualmente non supporta: interno . Questo modificatore significa che qualsiasi codice dichiarato nello stesso modulo che non è altrimenti limitato può accedere a questo elemento . (Un modulo è essenzialmente un file Jar.)

Questo è possibile in Java usando cose come OSGi, ma al momento non è nativo per la lingua. Java 9 introdurrà alcuni concetti che lo renderanno più realizzabile grazie alla possibilità di esportare selettivamente identificatori pubblici.

Ciò aggiunge un enorme vantaggio per la scrittura di API e implementazioni. Possiamo scrivere le nostre interfacce API come pubbliche , la nostra implementazione principale come classi pubbliche e tutto il codice di supporto da cui dipende come interno . Ciò significa che il codice esterno è costretto a passare attraverso l'API e non può accedere agli interni. Per esempio:

package com.baeldung.modifiers internal class Internal { } class Public { internal val i = 1 internal fun doSomething() { } }

Class Internal è accessibile solo dall'interno dello stesso modulo. Anche "val i" e "fun doSomething ()" sono accessibili solo dall'interno dello stesso modulo, anche se la classe in cui si trovano è accessibile da qualsiasi luogo.

3. Riepilogo

Nell'articolo abbiamo esaminato i modificatori di visibilità in Kotlin.

La maggior parte delle volte, le regole del modificatore di visibilità in Kotlin funzionano come ci aspetteremmo da Java. Tuttavia, c'è una grande differenza - che è l'introduzione dell'ambito interno - che è molto utile per progetti più grandi.