[Sammelthema] Objektorientierte Programmierung (OOP)

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Also, OOP in Lua funktioniert mittels Metatables.
      Dies sind glaube ich einfach nur Tabellen, die Informationen über die Tabelle selbst beinhalten, also, welche Metamethoden aufgerufen werden etc.
      Diese Metamethoden sind einfach nur Funktionen, die bei den Tabellen aufgerufen werden. So genau kann ich das jetzt leider nicht erklären, aber man kann ja mal Googeln oder so, da findet man sicherlich einiges.
      DEAL WITH IT.
    • DKong schrieb:

      Dies sind glaube ich einfach nur Tabellen, die Informationen über die Tabelle selbst beinhalten, also, welche Metamethoden aufgerufen werden etc.
      Diese Metamethoden sind einfach nur Funktionen, die bei den Tabellen aufgerufen werden. So genau kann ich das jetzt leider nicht erklären, aber man kann ja mal Googeln oder so, da findet man sicherlich einiges.

      Metatables beinhalten zusätzliche Informationen zu einer bestimmten Table, in der z.B. festgelegt wird, wie auf bestimmte "Aktionen" reagiert werden soll. Im Prinzip lassen sich die Metamethoden (Felder der Metatable) gut mit MTAs Events vergleichen.
      Wird z.B. auf einen Wert zugegriffen, der in der Table nicht existiert, wird die Metamethode __index aufgerufen, was man sich zu nutzen macht, um dieses "Pseudo-OOP" zu realisieren.

      LUA-Quellcode

      1. local tab = setmetatable({}, {__index = function(key, value) return 1337 end})

      Hierdurch wird festgelegt, dass immer "1337" zurückgegeben werden soll, wenn auf ein nicht definiertes Feld zugegriffen wird.

      LUA-Quellcode

      1. print(tab.xyz) -- Ausgabe: 1337
      2. tab.xyz = 1
      3. print(tab.xyz) -- Ausgabe: 1 (da jetzt ein Wert definiert ist)


      Abgesehen von den Metamethoden __index und __newindex, die im Zusammenhang mit der OOP oft zu finden sind, gibt es noch einige weitere Metamethoden. Ein Beispiel dafür ist __add. __add wird aufgerufen, wenn versucht wird 2 Tables miteinander zu addieren.

      LUA-Quellcode

      1. local tab1, tab2 = {x = 1, y = 2, z = 3}, {x = 2, y = 5, z = 10}
      2. local tab3 = tab1 + tab2 -- Fehler: attempt to perform arithmetic on ...
      3. -- Metatable setzen
      4. setmetatable(tab1, {__add = function(t1, t2) return {x = t1.x + t1.y, y = t1.y + t2.y, z = t1.z + t2.z} end})
      5. local tab3 = tab1 + tab2 -- Funktioniert

      ...und schon haben wir eine einfache Vektorklasse.

      Eine Liste mit Metamethoden findet man hier: lua-users.org/wiki/MetatableEvents
    • Es gibt noch andere Möglichkeiten die Syntaxvereinfachung der Objektorienteriungen Programmierung herbeizuführen.

      LUA-Quellcode

      1. klasse = {}
      2. function klasse.konstruktor()
      3. local this = {}
      4. local privateVariable = 1
      5. this.publicVariable = 2
      6. this.methode = function() return privateVariable end
      7. return this
      8. end
      9. eineInstanz = klasse.konstruktor() -- erstellt eine einzigartige Instanz
      10. print(eineInstanz.methode) -- gibt den Wert einer privaten Instanzvariable aus, volle Datenkapsleung
      11. print(eineInstanz.publicVariable) -- direkter Zugriff auf die öffentliche Instanzvariable
      12. klasse2 = {}
      13. function klasse2.konstrutkor2(_this)
      14. local this = _this
      15. this.neueInstanzVariable = 3
      16. end
      17. eineInstanz2 = klasse2.konstruktor2(eineInstanz) -- Vererbung
      Alles anzeigen


      Habs grade zusammengeschrieben, im groben dürfte es stimmen.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Shape ()

    • Danke euch.

      Ich habe hier mal ein kleines Beispiel von @Jusonex: genommen.

      Nur leider bekomme ich die ganze Zeit "metatableerror" zubekommen.

      LUA-Quellcode

      1. local tab = setmetatable({}, {__index = function(key, value) return "metatablerror" end});
      2. function outputTable ()
      3. local text = "Hallo Welt";
      4. outputChatBox(tab.text);
      5. end
      6. addCommandHandler("out",outputTable);


      M.f.G
    • Hey hey,
      da ich eigentlich aus anderen sprachen ein großer freund der objektorientierung bin, versuche ich mich gerade in lua etwas darin einzuarbeiten.

      Allerdings wird mir eins in lua nicht schlüssig

      wann benutze ich

      Quellcode

      1. .
      und wann

      Quellcode

      1. :
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)
    • Es kommt darauf an wie du die Objektorientierung umsetzt.
      Über Closures hast du nur den Punkt um Methoden aufzurufen oder
      Methoden zu definieren. Nutzt du die Table-Architektur oder die Steigerung
      mit den Metatables kannst du dir über den : die Übergabe von "self"
      in der Parameterliste sparen. Zudem ist ein Methodenaufruf mit : von nöten.
    • eine kleine frage noch an euch:

      wenn ich die metatable variante habe, wäre dann sowas möglich? oder besser gesagt sowas in der art?

      LUA-Quellcode

      1. Haus = {}
      2. Haus.__index = Haus
      3. function Haus:constructor( hx, hy, hz, irid, preis, miete, kasse, city, qm, stockwerke, wert )
      4. self.Coords={ tonumber(hx), tonumber(hy), tonumber(hz)}
      5. self.irid=tonumber(irid)
      6. self.preis=tonumber(preis)
      7. self.miete=tonumber(miete)
      8. self.kasse=tonumber(kasse)
      9. self.city=city
      10. self.qm=tonumber(qm)
      11. self.stockwerke=tonumber(stockwerke)
      12. self.wert=tonumber(wert)
      13. local Pickup=createPickup(hx,hy,hz,3,1273,5000)
      14. addEventHandler('onPickupHit',Pickup, self.FrageFunktion())
      15. end
      16. function Haus:FrageFunktion()
      17. end
      Alles anzeigen


      ich beziehe mich hauptsächlich auf:
      local Pickup=createPickup(hx,hy,hz,3,1273,5000)
      addEventHandler('onPickupHit',Pickup, self.FrageFunktion())
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von geramy ()

    • @geramy:
      Ja und nein.

      LUA-Quellcode

      1. addEventHandler('onPickupHit',Pickup, self.FrageFunktion())

      Das versucht den Rückgabewert der Funktion FrageFunktion als Eventhandler festzulegen. Das macht keinerlei Sinn. Du willst vermutlich

      LUA-Quellcode

      1. addEventHandler('onPickupHit',Pickup, self.FrageFunktion)

      Das würde prinzipiell funktionieren, jedoch wirst du auf ein Problem stoßen:
      Haus:FrageFunktion erhält so sehr komische Parameter übergeben.

      Um das zu erklären, ersteinmal eine Erklärung was der Doppelpunkt eigentlich macht.
      In einer Funktionsdefinition:
      In einer Funktionsdefinition "versteckt" der Doppelpunkt das erste übergebene Argument in der Variablen "self".

      LUA-Quellcode

      1. function Haus:zeigeInfo(aufrufername)
      2. end

      entspricht also:

      LUA-Quellcode

      1. function Haus.zeigeInfo(self, aufrufername)
      2. end


      In einem Funktionsaufruf
      In einem Funktionsaufruf übergibt der Doppelpunkt die Table, die vor dem Doppelpunkt steht als ersten Parameter an die Funktion.

      LUA-Quellcode

      1. meinHaus:zeigeInfo("Mein Aufrufername")

      entspricht also:

      LUA-Quellcode

      1. meinHaus.zeigeInfo(meinHaus, "Mein Aufrufername")



      Jetzt wieder zur Ursprungsfrage
      Wieso macht

      LUA-Quellcode

      1. addEventHandler('onPickupHit',Pickup, self.FrageFunktion)

      nicht, das was du erwartest?

      Beim Aufruf des onPickupHit Events wird als erster Parameter der Spieler übergeben, der das Pickup aufgesammelt hat. Daher ist dein self in der Funktion Haus:FrageFunktion kein Haus, sondern ein Spieler.

      Das lässt sich umgehen, indem man eine angepasste Funktion übergibt:

      LUA-Quellcode

      1. addEventHandler('onPickupHit',Pickup, function(player) self:FrageFunktion(player) end)

      Jetzt ist self wieder dein Haus und player wird als 1. (sichtbarer) Parameter an Haus:FrageFunktion übergeben.

      In der Classlib habe ich dafür eine kleine Hilfsfunktion, die den Code etwas sauberer hält.

      LUA-Quellcode

      1. addEventHandler('onPickupHit',Pickup, bind(self.FrageFunktion, self))
      Mich per PN bezüglich Freischaltungen zu nerven ist der beste Weg eine Freischaltung zu verhindern.

      neon-gaming.de