Klassen sind ein zentrales Konzept der objektorientierten Programmierung. In Crystal ist alles ein Objekt, jedes Objekt hat einen Typ und kann auf einige Methoden reagieren. Klassen sind Baupläne zum Erstellen von Objekten. Sie liefern Anfangswerte für den Zustand, etwa Variablen, und Implementierungen von Verhalten, etwa Methoden. Objekte sind Instanzen einer Klasse, die alle Instanzvariablen und Zustände enthalten.
Eine Klasse wird mit dem Schlüsselwort class definiert, gefolgt vom Namen der Klasse in UpperCamelCase.
class Account
end
Um eine Instanz einer Klasse zu erstellen, rufst du den Klassennamen mit der Methode new auf.
class Account
end
account = Account.new
Im obigen Beispiel ist die Variable account eine Instanz der Klasse Account.
Wenn du eine Instanz erstellst, fungiert eine spezielle Methode namens initialize als Konstruktor.
Sie wird aufgerufen, wenn eine Instanz erstellt wird.
Der Konstruktor ermöglicht es dir, den Anfangszustand der Instanz festzulegen.
Die Methode initialize kann Argumente entgegennehmen, die beim Erstellen einer Instanz übergeben werden.
class Account
def initialize(number)
5 + number # => 9
end
end
Account.new(4)
Die Methode initialize kann nicht selbst einen Wert zurückgeben. Stattdessen gibt new die neu erstellte Instanz zurück.
class Account
def initialize(number)
5 + number
end
end
Account.new(4)
# => #<Account:0x7f5dc33dcea0>
Eine Instanzmethode ist eine Methode, die für eine Instanz einer Klasse verfügbar ist und auf dieser Instanz aufgerufen werden kann.
Instanzmethoden werden mit dem Schlüsselwort def definiert, gefolgt vom Namen der Methode.
Sie werden innerhalb der Klassendefinition definiert.
class Account
def balance
100
end
end
account = Account.new
account.balance # => 100
Instanzvariablen sind Variablen, die in allen Methoden der Instanz verfügbar sind.
Um auf eine Instanzvariable zuzugreifen, musst du eine Instanzmethode definieren.
Sie können in der Methode initialize initialisiert werden.
Sie werden mit dem Präfix @ definiert.
class Account
def initialize
@balance = 100
end
def balance
@balance
end
end
account = Account.new
account.balance
# => 100
Instanzvariablen können auch innerhalb der Klassendefinition definiert werden.
class Account
@age = 0
end
Instanzvariablen können mit einem Argument initialisiert werden, das an die Methode initialize übergeben wird.
Da Crystal den Typ des bei der Initialisierung verwendeten Arguments nicht herleiten kann, muss er angegeben werden.
Wenn du mehr darüber lesen möchtest, kannst du hier nachlesen: Typinferenz.
Um den Typ der Variablen anzugeben, kannst du das Symbol : verwenden, gefolgt vom Typ.
Wenn du zum Beispiel eine Instanzvariable namens balance vom Typ Int32 erstellen möchtest, geht das so: @balance : Int32.
Oder wenn du eine Instanzvariable namens raining vom Typ Bool erstellen möchtest, geht das so: @raining : Bool.
Es gibt mehrere Möglichkeiten, das umzusetzen. Entweder deklarierst du in der Methode initialize das Argument mit dem Typ und weist dann die Instanzvariable dem Argument zu, wie im folgenden Beispiel:
class Account
def initialize(balance : Int32)
@balance = balance
end
def balance
@balance
end
end
account = Account.new(1)
account_2 = Account.new(5)
account.balance
# => 1
account_2.balance
# => 5
Eine andere Möglichkeit ist, den Typ der Instanzvariable in der Klassendefinition in der Form @<variable> : <Type> anzugeben, wie im folgenden Beispiel:
class Weather
@raining : Bool
def initialize(raining)
@raining = raining
end
def raining
@raining
end
end
weather = Weather.new(true)
weather.raining
# => true
Methoden können Instanzvariablen ändern. Diese Methoden können auf der Instanz der Klasse aufgerufen werden. Wenn eine Methode eine Instanzvariable ändert, ist diese Änderung nur in der Instanz der Klasse verfügbar, auf der du sie aufgerufen hast.
class Account
def initialize(balance : Int32)
@balance = balance
end
def withdraw(amount)
@balance -= amount
end
def balance
@balance
end
end
account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10
account_2.balance
# => 10
account.withdraw(5)
account.balance
# => 5
account_2.balance
# => 10
Klassenmethoden sind Methoden, die für eine Klasse definiert sind, aber nicht für ihre Instanzen.
Sie bieten eine Möglichkeit, Methoden zu erstellen, die nicht vom Zustand der Instanz abhängen.
Sie werden mit dem Schlüsselwort def definiert, gefolgt von self.<method name>.
self ist eine Referenz auf den Namensraum, aus dem self aufgerufen wird.
In diesem Fall bezieht es sich auf die Klasse Account.
Es wäre dasselbe, als hättest du Account. geschrieben, aber self. ist der bevorzugte Weg.
class Account
def self.balance
100
end
end
Account.balance
# => 100
Dein Freund Johannes liebt es, DIY-Hardware (also Hardware zum Selbermachen) zu bauen. Gerade hat er einen Entsafter gebaut, und Johannes freut sich riesig darüber. Johannes' Ziel ist es, jeden Morgen frischen Saft machen zu können.
Johannes' Entsafter hat jede Menge raffinierte Funktionen. Zum Beispiel ein eingebautes Messsystem, das dir sagt, wie viel Saft im Becher ist. Außerdem hat er einen Timer, der dir sagt, wie lange die Maschine schon läuft.
Johannes ist nicht der beste Programmierer, aber er möchte ein Programm schreiben, das die Maschine steuert. Deshalb hat er dich um Hilfe gebeten.
Die Maschine hat ein Debug-Licht. Es ist ganz einfach: Wenn die Maschine Strom hat, leuchtet das Debug-Licht. Das Programm läuft nur, wenn das Debug-Licht leuchtet.
Diese Methode sollte eine Klassenmethode namens JuiceMaker sein.
Definiere die Klassenmethode JuiceMaker.debug_light_on?, die true zurückgibt.
JuiceMaker.debug_light_on?
#=> true
Wenn die Maschine eingeschaltet wird, sollte sie eine Instanz einer Klasse namens JuiceMaker erzeugen.
Die Maschine soll einen initialisierten Zustand haben.
Der initialisierte Zustand sollte die folgenden Informationen enthalten:
false sein.Definiere den initialisierten Zustand, der die Menge Saft im Becher als Parameter entgegennimmt, und konstruiere den initialisierten Zustand.
Der initialisierte Zustand sollte eine Instanzvariable @running enthalten, die auf false gesetzt ist, und eine Instanzvariable @fluid, die auf einem Argument basiert, das beim Initialisieren der Klasse übergeben wird.
JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>
Die Maschine kann ein- und ausgeschaltet werden.
Du musst eine Methode definieren, die die Maschine einschaltet.
Wenn die Maschine eingeschaltet wird, sollte der Laufzustand auf true gesetzt werden.
Definiere die Methode JuiceMaker#start, die die Maschine einschaltet.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>
Die Maschine muss dir ihren Status mitteilen können.
Sie sollte true zurückgeben, wenn die Maschine läuft, und false, wenn die Maschine nicht läuft.
Definiere die Methode JuiceMaker#running?, die den Status der Maschine zurückgibt.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker.running?
#=> true
Die Maschine kann Saft in den Becher füllen. Die Maschine kann sagen, wie viel Saft in den Becher gefüllt wurde. Die Maschine braucht Hilfe, um zu wissen, wie viel Saft nach dem Hinzufügen im Becher ist.
Definiere die Methode JuiceMaker#add_fluid, die die hinzugefügte Saftmenge als Parameter entgegennimmt und die Saftmenge im Becher aktualisiert.
juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>
Die Maschine kann ein- und ausgeschaltet werden.
Du musst eine Methode definieren, die die Maschine ausschaltet.
Diese Methode wird nur aufgerufen, wenn die Maschine läuft.
Wenn die Maschine ausgeschaltet wird, sollte der Laufzustand auf false gesetzt werden.
Die Maschine braucht außerdem Hilfe bei der Bestimmung, wie viel Saft nach dem Ausschalten im Becher ist.
Die Maschine verbraucht fünf Einheiten Saft pro Minute.
Definiere die Methode JuiceMaker#stop, die die Anzahl der Minuten, die die Maschine gelaufen ist, als Parameter entgegennimmt und die Saftmenge im Becher zurückgibt, nachdem die Maschine ausgeschaltet wurde.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>
juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
Melde dich bei Exercism an, um Crystal mit 26 Konzepte142 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.