[Sammelthema] Objektorientierte Programmierung (OOP)

  • Hallo,


    Da mich viele gefragt haben, wie OOP genau funktioniert und was es bringt habe ich nun ein Sammelthema erstellt.


    Da ich selber noch kein OOP kann, könntet ihr ja für alle Ideen 'Sammeln'.


    Oder sogar Fehlermeldungen etc.


    M.f.G

  • 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.

  • Zitat von DKong

    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
    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
    print(tab.xyz) -- Ausgabe: 1337
    tab.xyz = 1
    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
    local tab1, tab2 = {x = 1, y = 2, z = 3}, {x = 2, y = 5, z = 10}
    local tab3 = tab1 + tab2 -- Fehler: attempt to perform arithmetic on ...
    -- Metatable setzen
    setmetatable(tab1, {__add = function(t1, t2) return {x = t1.x + t1.y, y = t1.y + t2.y, z = t1.z + t2.z} end})
    local tab3 = tab1 + tab2 -- Funktioniert


    ...und schon haben wir eine einfache Vektorklasse.


    Eine Liste mit Metamethoden findet man hier: http://lua-users.org/wiki/MetatableEvents

  • Es gibt noch andere Möglichkeiten die Syntaxvereinfachung der Objektorienteriungen Programmierung herbeizuführen.



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

    Einmal 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
    local tab = setmetatable({}, {__index = function(key, value) return "metatablerror" end});
    function outputTable ()
    local text = "Hallo Welt";
    outputChatBox(tab.text);
    end
    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

    Code
    .

    und wann

    Code
    :

    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 Instanz auch oft "Objekt" selbst genannt ist ein einzigartiges Exemplar der Daten und Methoden einer Klasse.

  • 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?



    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 :)

    2 Mal editiert, zuletzt von geramy ()

  • geramy:
    Ja und nein.

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


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

    Lua
    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
    function Haus:zeigeInfo(aufrufername)
    end


    entspricht also:

    Lua
    function Haus.zeigeInfo(self, aufrufername)
    end


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


    Lua
    meinHaus:zeigeInfo("Mein Aufrufername")


    entspricht also:

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



    Jetzt wieder zur Ursprungsfrage
    Wieso macht

    Lua
    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
    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
    addEventHandler('onPickupHit',Pickup, bind(self.FrageFunktion, self))

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!