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
endSekarang 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.
Tantangan
MudahMari 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:
- Suhu awal dalam Celsius (sebuah angka)
- 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: 212Ingat: 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
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Konsep "Self"
Tabel dengan Fungsi'self' EksplisitSintaks Titik DuaTitik vs Titik DuaRangkuman, Titik Bergerak4Proyek: Bank Digital
Penyiapan Proyekmethod Setoran7Polimorfisme & Overriding
Menimpa methodMemanggil method indukDuck TypingAntarmuka UmumMemeriksa TipeRingkasan: Peran Karyawan10Proyek: Pengelola Bentuk
Penyiapan Proyekclass Rectangleclass Circlemethod KelilingKumpulan BentukLuas TotalSaring Bentuk2Pola Prototype untuk class
Konsep PrototypeMenghubungkan dengan __indexKonstruktor :new()Menginisialisasi AtributInstans yang MandiriRangkuman: Pabrik Mobil5Pembebanan Operator dalam OOP
Menjumlahkan ObjekMengurangkan ObjekMenggabungkan ObjekMembandingkan Objek (<, >)Ulasan: Aritmetika Dompet8Enkapsulasi
Konvensi PenamaanClosure untuk PrivasiAkses melalui ClosureTabel Hanya-BacaLogika ValidasiRangkuman: Brankas Aman11Pola Desain (Ringan)
Fungsi FactoryTabel SingletonPola IteratorObserver (Listener)Rangkuman, Factory Logger3State dan Behavior pada object
Variabel InstansGetter methodSetter methodProperty TerhitungMemformat stringPemeriksaan KesetaraanRangkuman: Nilai Siswa6Dasar-Dasar Pewarisan
Menyiapkan PewarisanMewarisi methodMemperluas KonstruktorMenambahkan method untuk ChildSama vs UnikRangkuman: Hierarki BentukLatihan sendiri: Compiler Lua online