Nehmen wir an, wir müssen eine gemeinsame Klasse für Bäume (oder andere Objekte, die wir für die Lösung eines Problems benötigen) definieren. Da unsere Klassenstruktur recht komplex sein kann, ziehe ich es vor, die Methoden der Klasse nach ihrer Definition zu definieren. Unsere gemeinsame Klasse BaseTree
und einer unserer speziellen Klassen Tree
sind
class BaseTree
class BaseNode; end
class NodeA < BaseNode; end
end
class Container
class Tree < BaseTree; end
end
Nachdem wir die Klassenstruktur definiert haben, setzen wir #initialize
für alle Knotenpunkte.
class BaseTree::BaseNode
def initialize x
p x
end
end
Wenn wir es testen, dann ist alles in Ordnung
Container::Tree::NodeA.new(1)
# => 1
Wenn wir jedoch danach eine Methode auf folgende Weise hinzufügen
class Container::Tree::NodeA
def some_method; end
end
dann bricht es die Vererbung zwischen NodeA
y BaseNode
!!
Container::Tree::NodeA.new(2)
# ~> -:30:in `initialize': wrong number of arguments(1 for 0) (ArgumentError)
Um dies zu beheben, müssen wir es explizit definieren
class Container
class Tree < BaseTree
class NodeA < BaseNode; end # explicit inheritance
end
end
class Container::Tree::NodeA
def some_method; end
end
oder auf die folgende Weise
class Container::Tree::NodeA < Container::Tree::BaseNode
def some_method; end
end
class Container::Tree::NodeA < BaseTree::BaseNode
def some_method; end
end
Der letzte Weg muss nur einmal verwendet werden - beim ersten Hinzufügen einer Methode, und wir können die übergeordnete Klasse für spätere Definitionen auslassen
class Container::Tree::NodeA
def another_method; end
end
Danach funktioniert es gut, aber ich finde es ziemlich umständlich, vor allem, wenn es viele Baumarten und viele verschiedene Knoten gibt.
Gibt es einen eleganteren Weg, um solche Definitionen vorzunehmen?