Menu
CoddyTech

Akses melalui Closure

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 45 dari 70.

Variabel lokal privat tidak berguna jika kamu tidak pernah bisa berinteraksi dengannya. Solusinya adalah mendefinisikan method getter dan setter di dalam constructor, sehingga keduanya dapat mengakses cakupan closure.

Karena method ini dibuat di dalam :new(), method ini dapat "melihat" variabel lokal. Kamu menetapkannya langsung ke object:

local Counter = {}
Counter.__index = Counter

function Counter:new()
    local count = 0  -- Variabel privat
    
    local obj = {}
    
    -- Definisikan method di dalam konstruktor
    function obj:getCount()
        return count
    end
    
    function obj:increment()
        count = count + 1
    end
    
    setmetatable(obj, Counter)
    return obj
end

Sekarang variabel privat count dapat diakses, tetapi hanya melalui method yang kamu sediakan:

local c = Counter:new()
print(c:getCount())  -- 0
c:increment()
c:increment()
print(c:getCount())  -- 2
print(c.count)       -- nil (masih tersembunyi!)

Perhatikan bahwa :getCount() dan :increment() didefinisikan langsung pada obj, bukan pada tabel class. Setiap instance memiliki salinan fungsi-fungsi ini sendiri, dan masing-masing memiliki akses ke count privatnya sendiri. Inilah komprominya: privasi sejati membutuhkan sedikit lebih banyak memori karena method tidak dibagikan melalui prototype.

challenge icon

Tantangan

Mudah

Mari buat class Temperature yang menggunakan privasi berbasis closure untuk menyimpan nilai suhu dalam Celsius, dengan method getter dan setter yang didefinisikan di dalam konstruktor agar aksesnya terkendali!

Kamu akan mengatur kodemu dalam dua file:

  • Temperature.lua: Buat class yang menyimpan nilai suhu dalam variabel lokal di dalam konstruktor, sehingga benar-benar tersembunyi dari akses luar. Konstruktor :new(initialCelsius) harus menyimpan suhu dalam variabel lokal, lalu mendefinisikan method berikut langsung pada instance object:
    • :getCelsius(): mengembalikan suhu saat ini dalam Celsius
    • :setCelsius(value): memperbarui suhu ke nilai baru
    • :getFahrenheit(): mengembalikan suhu yang dikonversi ke Fahrenheit menggunakan rumus: (celsius * 9/5) + 32
  • main.lua: Gunakan require untuk module Temperature-mu dan baca dua nilai dari input: suhu awal dan suhu baru yang akan ditetapkan. Buat instance Temperature dengan nilai awal, cetak pembacaan Celsius dan Fahrenheit, lalu gunakan setter untuk mengubah suhu dan cetak kedua pembacaan itu lagi.

Kamu akan menerima dua input:

  1. Suhu awal dalam Celsius (sebuah angka)
  2. Suhu baru yang akan ditetapkan (sebuah angka)

Output-mu harus terdiri dari empat baris yang menampilkan pembacaan suhu sebelum dan sesudah perubahan:

Celsius: {initialValue}
Fahrenheit: {convertedInitial}
Celsius: {newValue}
Fahrenheit: {convertedNew}

Contohnya, jika input-nya 0 dan 100, output-nya harus seperti berikut:

Celsius: 0
Fahrenheit: 32
Celsius: 100
Fahrenheit: 212

Ingat: nilai suhu harus disimpan dalam variabel lokal di dalam :new(), bukan pada self. Method getter dan setter didefinisikan di dalam konstruktor, sehingga keduanya dapat mengakses variabel privat ini melalui closure. Jika kamu mencoba mengakses temp.celsius atau temp._celsius secara langsung, hasilnya harus nil!

Coba sendiri

-- Muat module Temperature dengan require
local Temperature = require('Temperature')

-- Baca nilai input
local initialTemp = tonumber(io.read())
local newTemp = tonumber(io.read())

-- TODO: Buat instance Temperature dengan nilai awal

-- TODO: Tampilkan nilai awal Celsius dan Fahrenheit

-- TODO: Gunakan setter untuk mengubah suhu menjadi newTemp

-- TODO: Tampilkan nilai Celsius dan Fahrenheit yang sudah diperbarui
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler Lua online