Menu
Coddy logo textTech

Closure'lar Aracılığıyla Erişim

Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 45 / 70.

Onlara hiçbir zaman erişemiyorsanız özel yerel değişkenler işe yaramaz. Çözüm, getter ve setter yöntemlerini yapıcının içinde tanımlamaktır; böylece bu yöntemler closure kapsamına erişebilir.

Bu yöntemler :new() içinde oluşturulduğundan yerel değişkenleri “görebilirler”. Onları doğrudan nesneye atarsınız:

local Counter = {}
Counter.__index = Counter

function Counter:new()
    local count = 0  -- Özel değişken
    
    local obj = {}
    
    -- Metodları yapıcı içinde tanımla
    function obj:getCount()
        return count
    end
    
    function obj:increment()
        count = count + 1
    end
    
    setmetatable(obj, Counter)
    return obj
end

Artık özel count değişkenine erişilebilir, ancak yalnızca sağladığın yöntemler aracılığıyla:

local c = Counter:new()
print(c:getCount())  -- 0
c:increment()
c:increment()
print(c:getCount())  -- 2
print(c.count)       -- nil (hâlâ gizli!)

:getCount() ve :increment() işlevlerinin sınıf tablosunda değil, doğrudan obj üzerinde tanımlandığına dikkat et. Her örnek, kendine ait özel count değişkenine erişebilen bu işlevlerin kendi kopyasını alır. Ödünleşim şudur: yöntemler prototip üzerinden paylaşılmadığı için gerçek gizlilik biraz daha fazla bellek kullanır.

challenge icon

Görev

Kolay

Sıcaklık değerini Celsius cinsinden depolamak için closure tabanlı gizlilik kullanan ve kontrollü erişim sağlamak üzere getter ve setter metotları constructor içinde tanımlanan bir Temperature sınıfı oluşturalım!

Kodunuzu iki dosyaya ayıracaksınız:

  • Temperature.lua: Sıcaklık değerinin constructor içindeki yerel bir değişkende depolandığı bir sınıf oluşturun: dışarıdan erişim tamamen gizli olmalıdır. Constructor :new(initialCelsius), sıcaklığı bir yerel değişkende depolamalı ve ardından şu metotları doğrudan nesne örneği üzerinde tanımlamalıdır:
    • :getCelsius(): mevcut sıcaklığı Celsius cinsinden döndürür
    • :setCelsius(value): sıcaklığı yeni bir değere günceller
    • :getFahrenheit(): (celsius * 9/5) + 32 formülünü kullanarak Fahrenheit'a dönüştürülmüş sıcaklığı döndürür
  • main.lua: Temperature modülünü Require edin ve girdiden iki değer okuyun: başlangıç sıcaklığı ve ayarlanacak yeni sıcaklık. Başlangıç değeriyle bir Temperature örneği oluşturun, Celsius ve Fahrenheit değerlerini yazdırın; ardından setter'ı kullanarak sıcaklığı değiştirin ve her iki değeri tekrar yazdırın.

İki girdi alacaksınız:

  1. Celsius cinsinden başlangıç sıcaklığı (bir sayı)
  2. Ayarlanacak yeni sıcaklık (bir sayı)

Çıktınız, değişiklikten önceki ve sonraki sıcaklık değerlerini gösteren dört satırdan oluşmalıdır:

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

Örneğin girdiler 0 ve 100 ise çıktı şöyle olmalıdır:

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

Unutmayın: sıcaklık değeri :new() içinde bir yerel değişkende depolanmalı, self üzerinde depolanmamalıdır. Getter ve setter metotları, closure aracılığıyla bu özel değişkene erişebilecekleri constructor içinde tanımlanır. temp.celsius veya temp._celsius değerlerine doğrudan erişmeye çalışmak nil döndürmelidir!

Kendin dene

-- Temperature modülünü yükle
local Temperature = require('Temperature')

-- Girdi değerlerini oku
local initialTemp = tonumber(io.read())
local newTemp = tonumber(io.read())

-- TODO: Başlangıç değeriyle bir Temperature örneği oluştur

-- TODO: Başlangıç Celsius ve Fahrenheit okumalarını yazdır

-- TODO: Sıcaklığı newTemp olarak değiştirmek için setter'ı kullan

-- TODO: Güncellenmiş Celsius ve Fahrenheit okumalarını yazdır
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Lua derleyicisi