Menu
Coddy logo textTech

Gemeinsam vs. Einzigartig

Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 35 von 70.

Bei der Arbeit mit Vererbung ist es wichtig zu verstehen, wo die einzelnen Daten liegen. Einige Attribute werden geteilt – in der Elternklasse definiert und für alle Kindklassen zugänglich. Andere sind einzigartig – speziell in der Kindklasse oder Instanz erstellt.

Betrachten Sie diese Hierarchie:

local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia"  -- Gemeinsam genutzt: auf der Klasse definiert

function Animal:new(name)
    local obj = {name = name}  -- Einzigartig: auf jeder Instanz gespeichert
    setmetatable(obj, Animal)
    return obj
end
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark"  -- Wird von allen Dogs geteilt

function Dog:new(name, breed)
    local obj = Animal.new(Animal, name)
    obj.breed = breed  -- Einzigartig: jeder Dog hat seine eigene Rasse
    setmetatable(obj, Dog)
    return obj
end

Wenn Sie eine Dog-Instanz erstellen, existieren einige Werte direkt auf dem Objekt, während andere über die Lookup-Kette gefunden werden:

local rex = Dog:new("Rex", "German Shepherd")

-- Einzigartig für diese Instanz (gespeichert auf rex)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"
-- Geteilt (über Lookup gefunden)
print(rex.sound)   -- "bark" (von Dog)
print(rex.kingdom) -- "Animalia" (von Animal)

Der entscheidende Unterschied: Felder, die obj in Konstruktoren zugewiesen werden, sind für jede Instanz eindeutig, während Felder, die direkt in Klassentabellen definiert sind, von allen Instanzen dieser Klasse und deren Unterklassen gemeinsam genutzt werden.

challenge icon

Aufgabe

Einfach

Lassen Sie uns untersuchen, wie Daten durch eine Vererbungshierarchie fließen, indem wir ein Klassensystem aus Creature und Dragon aufbauen. Sie werden aus erster Hand sehen, welche Attribute von allen Instanzen gemeinsam genutzt werden und welche für jedes einzelne Objekt eindeutig sind.

Sie werden Ihren Code auf drei Dateien verteilen:

  • Creature.lua: Definieren Sie Ihre Elternklasse mit einem gemeinsamen Attribut auf Klassenebene world = "Fantasy Realm", das alle Kreaturen teilen. Fügen Sie einen :new(name)-Konstruktor hinzu, der den Namen der Kreatur als Instanzattribut speichert.
  • Dragon.lua: Definieren Sie Ihre Kindklasse, die von Creature erbt. Fügen Sie ein gemeinsames Attribut auf Klassenebene element = "fire" hinzu, das alle Drachen teilen. Ihr :new(name, color)-Konstruktor sollte den Eltern-Konstruktor für den Namen aufrufen und dann color als eindeutiges Instanzattribut für jeden Drachen hinzufügen.
  • main.lua: Erstellen Sie zwei verschiedene Drachen und inspizieren Sie deren Attribute, um den Unterschied zwischen gemeinsamen und eindeutigen Daten zu demonstrieren.

Sie erhalten zwei Eingaben:

  1. Den Namen und die Farbe des ersten Drachen, getrennt durch ein Komma (z. B. Smaug,red)
  2. Den Namen und die Farbe des zweiten Drachen, getrennt durch ein Komma (z. B. Draco,gold)

Erstellen Sie in Ihrer Hauptdatei beide Drachen mit ihren jeweiligen Namen und Farben. Geben Sie dann die folgenden Informationen in genau dieser Reihenfolge aus:

  1. name des ersten Drachen
  2. color des ersten Drachen
  3. name des zweiten Drachen
  4. color des zweiten Drachen
  5. element des ersten Drachen (gemeinsam genutzt von der Dragon-Klasse)
  6. element des zweiten Drachen (gemeinsam genutzt von der Dragon-Klasse)
  7. world des ersten Drachen (gemeinsam genutzt von der Creature-Klasse)

Wenn die Eingaben beispielsweise Smaug,red und Draco,gold sind, sollte die Ausgabe wie folgt aussehen:

Smaug
red
Draco
gold
fire
fire
Fantasy Realm

Beachten Sie, dass name und color für jeden Drachen unterschiedlich sind (eindeutige Instanzattribute), während element und world für beide gleich sind (gemeinsame Klassenattribute, die über die Lookup-Kette gefunden werden).

Spickzettel

In Vererbungshierarchien können Attribute entweder gemeinsam genutzt (auf der Klassentabelle definiert) oder einzigartig (auf einzelnen Instanzen gespeichert) sein.

Gemeinsam genutzte Attribute werden direkt in Klassentabellen definiert und über die Metatabellen-Suchkette aufgerufen:

local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia"  -- Gemeinsam für alle Animals

Einzigartige Attribute werden dem Instanzobjekt (obj) in Konstruktoren zugewiesen:

function Animal:new(name)
    local obj = {name = name}  -- Einzigartig für jede Instanz
    setmetatable(obj, Animal)
    return obj
end

Unterklassen können ihre eigenen gemeinsam genutzten Attribute haben, während sie Attribute der Elternklasse erben:

local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark"  -- Gemeinsam für alle Dogs

function Dog:new(name, breed)
    local obj = Animal.new(Animal, name)  -- Eltern-Konstruktor aufrufen
    obj.breed = breed  -- Einzigartiges Attribut der Unterklasse hinzufügen
    setmetatable(obj, Dog)
    return obj
end

Zugriff auf Attribute:

local rex = Dog:new("Rex", "German Shepherd")

-- Einzigartig (direkt auf rex gespeichert)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"

-- Gemeinsam genutzt (über Metatabellen-Suche gefunden)
print(rex.sound)   -- "bark" (von der Dog-Klasse)
print(rex.kingdom) -- "Animalia" (von der Animal-Klasse)

Probier es selbst

-- main.lua: Drachen erstellen und gemeinsame vs. eindeutige Attribute demonstrieren

local Dragon = require('Dragon')

-- Eingabe für den ersten Drachen lesen (Name, Farbe)
local input1 = io.read()
-- Eingabe für den zweiten Drachen lesen (Name, Farbe)
local input2 = io.read()

-- TODO: Die erste Eingabe parsen, um Name und Farbe zu extrahieren
-- Hinweis: string.match mit dem Muster "([^,]+),([^,]+)" verwenden

-- TODO: Die zweite Eingabe parsen, um Name und Farbe zu extrahieren

-- TODO: Den ersten Drachen mit seinem Namen und seiner Farbe erstellen

-- TODO: Den zweiten Drachen mit seinem Namen und seiner Farbe erstellen

-- TODO: Folgendes in dieser Reihenfolge ausgeben:
-- 1. Name des ersten Drachens
-- 2. Farbe des ersten Drachens
-- 3. Name des zweiten Drachens
-- 4. Farbe des zweiten Drachens
-- 5. Element des ersten Drachens (von der Dragon-Klasse geteilt)
-- 6. Element des zweiten Drachens (von der Dragon-Klasse geteilt)
-- 7. Welt des ersten Drachens (von der Creature-Klasse geteilt)
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming