0Pricing
Lua Academy · Ders

Geçersiz Kılma ve Çok Biçimlilik

Üst sınıf yöntemlerini geçersiz kılın ve çalışma zamanında çok biçimli dağıtım sağlayın.

Geçersiz Kılma ve Çok Biçimlilik, CoddyKit'te ücretsiz bir Lua Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Lua Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Lua Academy kursu toplamda 4 dersten oluşur.

Yöntemlerin Üzerine Yazma

Alt sınıf, aynı ada sahip bir yöntem tanımlayarak üst sınıf yönteminin üzerine yazar. Alt sınıf örneği üzerinde çağrıldığında alt sınıfın sürümü çalışır. Üst sınıfın sürümüne yine Parent.method(self) aracılığıyla erişilebilir.

local Shape={} Shape.__index=Shape
function Shape:area() return 0 end
function Shape:describe() print(type(self).." area="..self:area()) end

local Circle={} Circle.__index=Circle
setmetatable(Circle,{__index=Shape})
function Circle.new(r) return setmetatable({r=r},Circle) end
function Circle:area() return math.pi*self.r^2 end

local Square={} Square.__index=Square
setmetatable(Square,{__index=Shape})
function Square.new(s) return setmetatable({s=s},Square) end
function Square:area() return self.s^2 end

Circle.new(5):describe()
Square.new(4):describe()

Çok Biçimli Yönlendirme

Çok biçimlilik, farklı nesne türlerinin aynı mesaja farklı şekillerde yanıt vermesidir. Herhangi bir "şekli" kabul eden ve :area() çağrısı yapan bir işlev, her şekil türüyle çalışır; her tür kendi uygulamasıyla yanıt verir.

local shapes={
  Circle.new(3),
  Square.new(4),
  Circle.new(1),
}

local total=0
for _,shape in ipairs(shapes) do
  total=total+shape:area()
end
print(string.format("Total area: %.2f",total))

Ördek Tiplemesi

Lua ördek tiplemesi kullanır: Bir nesnede yöntem varsa nesne çalışır. Resmî bir arayüz bildirimi gerekmez. :speak() çağrısı yapan bir işlev, sınıfından bağımsız olarak speak yöntemi bulunan her nesneyle çalışır.

local function makeNoise(obj)
  if type(obj.speak)=="function" then
    obj:speak()
  else
    print("(silent)")
  end
end

local Duck={speak=function(self) print("Quack!") end}
local Robot={speak=function(self) print("Beep boop!") end}
local Rock={}

makeNoise(Duck)   -- Quack!
makeNoise(Robot)  -- Beep boop!
makeNoise(Rock)   -- (silent)

İşleçlerde Çok Biçimlilik

__add gibi meta yöntemler, işleçler için çok biçimlilik sağlar. Farklı türler, __add tanımladıkları sürece + işleçine kendi anlamlarıyla yanıt verebilir.

local Vec2={} Vec2.__index=Vec2
Vec2.__add=function(a,b) return Vec2.new(a.x+b.x,a.y+b.y) end
Vec2.__tostring=function(v) return "("..v.x..","..v.y..")" end
function Vec2.new(x,y) return setmetatable({x=x,y=y},Vec2) end

local Color={} Color.__index=Color
Color.__add=function(a,b)
  return Color.new(math.min(255,a.r+b.r),math.min(255,a.g+b.g),math.min(255,a.b+b.b))
end
function Color.new(r,g,b) return setmetatable({r=r,g=g,b=b},Color) end

print(tostring(Vec2.new(1,2)+Vec2.new(3,4)))  -- (4,6)

Ziyaretçi Kalıbı

Ziyaretçi kalıbı, işlemleri nesnelerden ayırır. Bir işlem, farklı türlerdeki nesneleri "ziyaret eder" ve türe göre uygun yöntemi çağırır. Türleri değiştirmeden türe göre farklılaşması gereken işlemler için kullanılır.

local function printInfo(obj)
  local mt = getmetatable(obj)
  if mt == Circle then
    print(string.format("Circle r=%.1f area=%.2f",obj.r,obj:area()))
  elseif mt == Square then
    print(string.format("Square s=%.1f area=%.2f",obj.s,obj:area()))
  end
end
for _,s in ipairs({Circle.new(3),Square.new(4)}) do
  printInfo(s)
end

Arayüz Tablosu

Bir arayüzü, yöntem adlarından oluşan bir tablo olarak tanımlayın. Bir nesneyi çok biçimli olarak kullanmadan önce gerekli tüm yöntemleri uyguladığını doğrulayın.

local function implements(obj, interface)
  for _, method in ipairs(interface) do
    if type(obj[method]) ~= "function" then
      return false, "missing: "..method
    end
  end
  return true
end

local Drawable = {"draw","resize","move"}

local Widget = {
  draw=function(self) print("draw "..self.type) end,
  resize=function(self,w,h) self.w,self.h=w,h end,
  move=function(self,x,y) self.x,self.y=x,y end,
  type="button"
}

local ok,err = implements(Widget,Drawable)
print(ok,err)  -- true nil

Yöntem Var mı Denetimi

İsteğe bağlı bir yöntemi çok biçimli olarak çağırmadan önce nesnede bu yöntemin bulunup bulunmadığını denetleyin. Böylece ortak bir temel sınıf gerektirmeden isteğe bağlı yetenekler sağlanabilir.

local function maybeUpdate(obj, dt)
  if type(obj.update)=="function" then
    obj:update(dt)
  end
end

local objects={
  {x=0,y=0,update=function(self,dt) self.x=self.x+10*dt end},
  {x=0,y=0},  -- no update
  {x=0,y=0,update=function(self,dt) self.y=self.y+5*dt end},
}

for _,o in ipairs(objects) do maybeUpdate(o,1) end
for _,o in ipairs(objects) do print(o.x,o.y) end

Türe Dayalı Yönlendirme Tablosu

if/elseif zincirleri yerine bir yönlendirme tablosu kullanın: tür adlarını işleyici işlevlerle eşleyin. Bu, tablo güdümlü çok biçimlilik kalıbıdır.

local handlers={
  number  = function(v) return "num:"..v end,
  string  = function(v) return "str:\"".."..v.."\"" end,
  boolean = function(v) return "bool:"..(v and "T" or "F") end,
  table   = function(v) return "tbl:#"..tostring(#v) end,
}

local function describe(v)
  local h=handlers[type(v)]
  return h and h(v) or "unknown"
end

print(describe(42))
print(describe("hello"))
print(describe({1,2,3}))

Kovaryant Dönüşler

Alt sınıf yöntemleri, üst sınıf yöntemlerinden daha özel türler döndürebilir (kovaryant dönüş). Lua dinamik türlemeli olduğundan bu doğaldır; alt sınıfın fabrika işlevi yalnızca bir üst sınıf değil, alt sınıf örneği döndürür.

local Base={} Base.__index=Base
function Base.new() return setmetatable({type="base"},Base) end
function Base:copy() return Base.new() end

local Child={} Child.__index=Child
setmetatable(Child,{__index=Base})
function Child.new(extra)
  local self=setmetatable({type="child"},Child)
  self.extra=extra; return self
end
function Child:copy() return Child.new(self.extra) end  -- covariant

local c=Child.new("hello")
local c2=c:copy()
print(c2.extra,getmetatable(c2)==Child)  -- hello true

Çok Biçimlilik Özeti

Lua'da çok biçimlilik pratikte şöyle çalışır: aynı yöntem adı, türe göre farklı davranış. Bu; meta tablo tabanlı nesne yönelimli programlama, ördek tiplemesi denetimleri veya yönlendirme tablolarıyla sağlanır. Resmî bir arayüz sistemi gerekmez; tutarlı yöntem adlandırma kuralları yeterlidir.

-- Three ways to achieve polymorphism:
-- 1. Metatable inheritance + method override
-- 2. Duck typing: just call it if it exists
-- 3. Dispatch table: map type -> handler

local function area(shape)
  -- Duck typing approach:
  assert(type(shape.area)=="function","needs area()")
  return shape:area()
end

print(area({area=function() return 16 end}))  -- 16

Çok Biçimlilik Sorusu

Lua'da çok biçimlilik nasıl çalışır?

Özet: Üzerine Yazma ve Çok Biçimlilik

Üst sınıf yöntemlerini alt sınıfta yeniden tanımlayarak üzerine yazın. Lua, çağrıları __index zinciri boyunca aşağıdan yukarıya çözümler ve böylece çalışma zamanında çok biçimli yönlendirmeyi doğal olarak sağlar.

Sıkça Sorulan Sorular

“Geçersiz Kılma ve Çok Biçimlilik” dersi ücretsiz mi?

Evet — “Geçersiz Kılma ve Çok Biçimlilik” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Lua Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Lua Academy kursu toplamda 4 dersten oluşur.

“Geçersiz Kılma ve Çok Biçimlilik” dersinde ne öğreneceğim?

Üst sınıf yöntemlerini geçersiz kılın ve çalışma zamanında çok biçimli dağıtım sağlayın. Lua Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Lua Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Lua Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Geçersiz Kılma ve Çok Biçimlilik” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Lua Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Lua Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. __index Zincirleme ile Tekli Kalıtım
  2. Üst Sınıf Yöntemlerini super ile Çağırma
  3. Karışım Örüntüleri
  4. Geçersiz Kılma ve Çok Biçimlilik
← Lua Academy Sayfasına Dön