Lập trình Kotlin - Phạm vi truy cập

Mức truy cập thuộc tính và phương thức trong Kotlin

Khi xây dựng một class, chắc chắn bạn sẽ phải xác định phạm vi truy cập cho các thuộc tính và phương thức trong class đó. Mục đích của việc này nhằm quy định các thành phần nào có thể được truy cập, thay đổi từ bên ngoài, thành phần nào là riêng tư.

Có thể hiểu phạm vi truy xuất này cũng giống như biến toàn cục và biến cục bộ. Biến toàn cục có thể được truy cập từ tất cả các hàm sau khai báo nó, còn biến cục bộ chỉ có thể được truy cập nội bộ trong hàm.

Trong Kotlin, phạm vi truy cập được xác định qua 4 từ khóa: public, private, protected và internal.

  • public: Các thành phần mang thuộc tinh này đều có thể được truy cập từ bất kỳ hàm nào, dù ở trong hay ngoài lớp.
  • private: Các thành phần mang thuộc tinh này chỉ có thể được truy cập bên trong phạm vi lớp. Vì trong Kotlin cho phép định nghĩa phương thức ngoài khai báo lớp nên phạm vi lớp được hiểu là bên trong khai báo lớp và bên trong các định nghĩa thuộc lớp. 
  • protected: Các thành phần mang thuộc tinh này chỉ có thể được truy cập bên trong phạm vi lớp và các lớp con kế thừa nó. Như vậy, nếu một lớp không có lớp con kế thừa nó thì phạm vi protected cũng giống như private
  • internal: Các khai báo được đánh dấu với chỉ định truy cập internal có thể được truy cập ("nhìn thấy") mọi nơi trong cùng 1 module. 1 module là 1 tập các file Kotlin được biên dịch cùng với nhau

1. Mức truy cập public

Các khai báo được đánh dấu với chỉ định truy cập public có thể được truy cập ("nhìn thấy") mọi nơi. public là chỉ định truy cập mặc định trong Kotlin (1 khai báo mà không có chỉ định truy cập thì mặc định là public)

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

Ở ví vụ trên ta thấy không có từ khóa public. Trong Kotlin mặc định là phblic. Chúng ta có thể viết thêm từ khóa public vào vì dụ trên

public class publicExample {
   public val i = 1
   
   public fun doSomething() {
   }
}

2. Mức truy cập private

Các khai báo được đánh dấu với chỉ định truy cập private có thể được truy cập ("nhìn thấy") bên trong file/class chứa khai báo

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

Trong ví dụ trên, lớp privateExample chỉ có thể truy cập được từ bên trong cùng một tệp nguồn và biến i và phương thức doSomething chỉ có thể được truy cập từ bên trong lớp privateExample.

Ví dụ đơn giản cho thấy việc sử dụng các thành viên private:

open class A() {
   private val i = 1
   
   fun doSomething(){
      println("Inside doSomething" )
      println("Value of i is $i" )
   }
}

class B : A() {
   fun printValue(){
       doSomething()
       // println("Value of i is $i" )
   }
}

fun main(args: Array<String>) {  
   val a = A()
   val b = B()
   
   b.printValue()
}  

Kết quả:

Inside doSomething
Value of i is 1

3. Mức truy cập protected

Các khai báo được đánh dấu với chỉ định truy cập protected có thể được truy cập ("nhìn thấy") bên trong file chứa khai báo và các class con (subclasses). protected không được phép cho các khai báo top-level.

Ví dụ:

package one;

class A() {
   protected val i = 1
}
class B : A() {
   fun getValue() : Int {
      return i
   }
}

Trong ví dụ trên, biến i được khai báo là protected. Nên nó có thể truy cập bên trong lớp và lớp thừa kế

Ví dụ sử dụng từ khóa protected cho các thành viên

open class A() {
   protected val i = 1
   
   protected fun doSomething(){
      println("Inside doSomething" )
      println("Value of i is $i" )
   }
}

class B : A() {
   fun printValue(){
       doSomething()
       println("Value of i is $i" )
   }
}

fun main(args: Array<String>) {  
   val a = A()
   val b = B()
   
   //a.doSomething()
   
   b.printValue()
}  

Kết quả:

Inside doSomething
Value of i is 1
Value of i is 1

4. Mức truy cập internal

Các khai báo được đánh dấu với chỉ định truy cập internal có thể được truy cập ("nhìn thấy") mọi nơi trong cùng 1 module. 1 module là 1 tập các file Kotlin được biên dịch cùng với nhau

  • IntelliJ IDEA module
  • Maven project
  • Gradle source set
  • 1 tập các file được biên dịch với 1lệnh <kotlinc> Ant task

Ví dụ:

package one

internal class InternalExample {
}

class publicExample{
    internal val i = 1

    internal fun doSomething() {
    }
}

Trong ví dụ trên, lớp InternalExample chỉ có thể truy cập từ bên trong cùng một hàm, tương tự biến i và hàm doSomething () cũng chỉ có thể truy cập từ bên trong cùng một hàm, mặc dù lớp publicExample có thể được truy cập từ bất kỳ đâu vì lớp này mặc định là public.

Ví dụ về cách sử dụng từ khóa internal

package com.tutorialspoint.modifiers

open class A() {
   internal val i = 1
   
   internal fun doSomething(){
      println("Inside doSomething" )
      println("Value of i is $i" )
   }
}
class B : A() {
   fun printValue(){
       doSomething()
       println("Value of i is $i" )
   }
}

fun main(args: Array<String>) {  
   val a = A()
   val b = B()
   
   a.doSomething()
   
   b.printValue()
}  

Kết quả:

Inside doSomething
Value of i is 1
Inside doSomething
Value of i is 1
Value of i is 1