Menu
Coddy logo textTech

Module und include

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 27 von 57.

Ein Modul ist eine benannte Gruppe von Methoden. Es kann keine Objekte erstellen, aber eine Klasse kann es mit include einbinden, und dann verfügt jede Instanz über die Methoden des Moduls, als hätte die Klasse sie definiert. Dies wird als Mixin bezeichnet:

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Person
  include Greetable
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

puts Person.new("Ada").greet

Ausgabe:

Hello, I am Ada

Die Methoden eines Moduls können Methoden aufrufen, die die Klasse bereitstellt, wie etwa das obige name. Daher kann ein Modul sehr unterschiedlichen Klassen dienen, solange jede davon das anbietet, was das Modul verwendet:

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Robot
  include Greetable

  def name
    "R2"
  end
end

class City
  include Greetable

  def name
    "Paris"
  end
end

puts Robot.new.greet
puts City.new.greet

Ausgabe:

Hello, I am R2
Hello, I am Paris

Eine Klasse hat nur eine Oberklasse, kann aber beliebig viele Module einbinden. include? fragt, ob eine Klasse ein Modul einbindet, und das Modul erscheint in ancestors, direkt nach der Klasse. Dort sucht Ruby nach deren Methoden:

module Swimmer
  def swim
    "swimming"
  end
end

module Flyer
  def fly
    "flying"
  end
end

class Duck
  include Swimmer
  include Flyer
end

d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)

Ausgabe:

swimming, flying
true
[Duck, Flyer, Swimmer]

Module gruppieren außerdem verwandte Klassen und Konstanten unter einem Namen, einem Namensraum, damit keine Namenskonflikte entstehen. Shop::Item und Game::Item sind verschiedene Klassen:

module Shop
  TAX = 0.2

  class Item
    def label
      "shop item, tax #{TAX}"
    end
  end
end

puts Shop::Item.new.label
puts Shop::TAX

Ausgabe:

shop item, tax 0.2
0.2
challenge icon

Aufgabe

Einfach

Vervollständige die Module und Klassen. Greetable#greet gibt Hello, I am Ada zurück und verwendet dabei den name des Objekts. Walkable#walk(steps) addiert die Schritte zu einem in @steps gespeicherten Zähler (der beim ersten Mal mit nil beginnt) und gibt Ada walked 30 steps, die laufende Summe, zurück. Person bindet beide Module ein; Robot bindet nur Greetable ein, und sein Name ist R-, gefolgt von einer Seriennummer.

Der bereitgestellte Code erstellt anhand der ersten Zeile (Ada 7) eine Person und einen Roboter, führt dann die Befehle greet p, greet r oder walk 10 (für die Person) aus und gibt jedes Ergebnis aus. Schließlich gibt er robot walks: false aus.

Dein Code gehört in greetable.rb, walkable.rb, person.rb und robot.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'

# Gelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
input = []
while (line = gets)
  input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
  command, arg = line.split
  if command == "walk"
    puts person.walk(arg.to_i)
  else
    target = arg == "p" ? person : robot
    puts target.greet
  end
end
puts "robot walks: #{Robot.include?(Walkable)}"
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 Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler