Le classi sono un concetto centrale nella programmazione orientata agli oggetti. In Crystal, tutto è un oggetto, ogni oggetto ha un tipo e può rispondere ad alcuni metodi. Le classi sono modelli per creare oggetti: forniscono valori iniziali per lo stato, come le variabili, e implementazioni di comportamento, come i metodi. Gli oggetti sono istanze di classe che contengono tutte le variabili di istanza e gli stati.
Una classe si definisce con la parola chiave class, seguita dal nome della classe scritto in UpperCamelCase.
class Account
end
Per creare un'istanza di una classe, chiama il nome della classe usando il metodo new.
class Account
end
account = Account.new
Nell'esempio qui sopra, la variabile account è un'istanza della classe Account.
Quando si crea un'istanza, un metodo speciale chiamato initialize funge da costruttore.
Viene chiamato quando si crea un'istanza.
Il costruttore permette di impostare lo stato iniziale dell'istanza.
Il metodo initialize può accettare argomenti, che vengono passati quando si crea un'istanza.
class Account
def initialize(number)
5 + number # => 9
end
end
Account.new(4)
Il metodo initialize non può restituire manualmente un valore: al suo posto, new restituisce l'istanza appena creata.
class Account
def initialize(number)
5 + number
end
end
Account.new(4)
# => #<Account:0x7f5dc33dcea0>
Un metodo di istanza è un metodo disponibile per un'istanza di una classe, e può essere chiamato su quell'istanza.
I metodi di istanza si definiscono con la parola chiave def, seguita dal nome del metodo.
Si definiscono all'interno della definizione della classe.
class Account
def balance
100
end
end
account = Account.new
account.balance # => 100
Le variabili di istanza sono variabili disponibili in tutti i metodi dell'istanza.
Per accedere a una variabile di istanza devi definire un metodo di istanza.
Possono essere inizializzate nel metodo initialize.
Si definiscono usando il prefisso @.
class Account
def initialize
@balance = 100
end
def balance
@balance
end
end
account = Account.new
account.balance
# => 100
Le variabili di istanza possono anche essere definite all'interno della definizione della classe.
class Account
@age = 0
end
Le variabili di istanza possono essere inizializzate con un argomento passato al metodo initialize.
Poiché Crystal non riesce a inferire il tipo dell'argomento usato durante l'inizializzazione, questo va specificato.
Se vuoi saperne di più, puoi leggere: type-inference.
Per specificare il tipo della variabile puoi usare il simbolo :, seguito dal tipo.
Per esempio, se vuoi creare una variabile di istanza chiamata balance di tipo Int32, puoi fare così: @balance : Int32.
Oppure, se vuoi creare una variabile di istanza chiamata raining di tipo Bool, puoi fare così: @raining : Bool.
Ci sono diversi modi per farlo. Uno è dichiarare l'argomento con il tipo nel metodo initialize e poi assegnare la variabile di istanza all'argomento, come nell'esempio seguente:
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
Un altro modo è dichiarare il tipo della variabile di istanza nella definizione della classe nella forma: @<variable> : <Type>, come nell'esempio seguente:
class Weather
@raining : Bool
def initialize(raining)
@raining = raining
end
def raining
@raining
end
end
weather = Weather.new(true)
weather.raining
# => true
I metodi possono modificare le variabili di istanza. Questi metodi possono essere chiamati sull'istanza della classe. Quando un metodo modifica una variabile di istanza, quella modifica è disponibile solo nell'istanza della classe su cui l'hai chiamato.
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
I metodi di classe sono metodi definiti per una classe, ma non per le sue istanze.
Offrono un modo per creare metodi che non dipendono dallo stato dell'istanza.
Si definiscono con la parola chiave def, seguita da self.<method name>.
self è un riferimento al namespace da cui viene chiamato self.
In questo caso, si riferisce alla classe Account.
Sarebbe lo stesso che scrivere Account., ma self. è il modo preferito.
class Account
def self.balance
100
end
end
Account.balance
# => 100
Il tuo amico Johannes adora costruire hardware fai da te (DIY). Ha appena costruito una macchina per il succo e Johannes ne è entusiasta. L'obiettivo di Johannes è riuscire a preparare un succo fresco ogni mattina.
La macchina per il succo di Johannes ha tante funzionalità sofisticate. Per esempio un sistema di misurazione integrato, che ti dice quanto succo c'è nella tazza. Ha anche un timer, che ti dice da quanto tempo la macchina è in funzione.
Johannes non è un grande programmatore, ma vuole scrivere un programma per controllare la macchina. Per questo ti ha chiesto aiuto.
La macchina ha una luce di debug, un meccanismo semplice: se la macchina è alimentata, la luce di debug è accesa. Il programma funziona solo se la luce di debug è accesa.
Questo metodo dovrebbe essere un metodo di classe chiamato JuiceMaker.
Definisci il metodo di classe JuiceMaker.debug_light_on? che restituisce true.
JuiceMaker.debug_light_on?
#=> true
Quando la macchina viene accesa, dovrebbe creare un'istanza di una classe chiamata JuiceMaker.
La macchina dovrebbe avere uno stato inizializzato, cioè le informazioni che descrivono la situazione attuale della macchina.
Lo stato inizializzato dovrebbe contenere le seguenti informazioni:
false quando la macchina viene accesa.Definisci lo stato inizializzato, che prende come parametro la quantità di succo nella tazza, e costruisci lo stato inizializzato.
Lo stato inizializzato dovrebbe ospitare una variabile di istanza @running impostata a false, e una variabile di istanza @fluid basata su un argomento passato quando la classe viene inizializzata.
JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>
La macchina può essere accesa e spenta.
Devi definire un metodo per accendere la macchina.
Quando la macchina viene accesa, lo stato di funzionamento dovrebbe essere impostato a true.
Definisci il metodo JuiceMaker#start, che accende la macchina.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>
La macchina deve poter indicare il proprio stato.
Dovrebbe restituire true se la macchina è in funzione, e false se non lo è.
Definisci il metodo JuiceMaker#running?, che restituisce lo stato della macchina.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker.running?
#=> true
La macchina può aggiungere succo alla tazza. La macchina sa quanto succo viene aggiunto alla tazza. La macchina ha bisogno di aiuto per sapere quanto succo c'è nella tazza dopo che è stato aggiunto.
Definisci il metodo JuiceMaker#add_fluid, che prende come parametro la quantità di succo aggiunta e aggiorna la quantità di succo nella tazza.
juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>
La macchina può essere accesa e spenta.
Devi definire un metodo per spegnere la macchina.
Questo metodo viene chiamato solo quando la macchina è in funzione.
Quando la macchina viene spenta, lo stato di funzionamento dovrebbe essere impostato a false.
La macchina ha anche bisogno di aiuto per determinare quanto succo c'è nella tazza dopo che è stata spenta.
La macchina consuma cinque unità di succo al minuto.
Definisci il metodo JuiceMaker#stop, che prende come parametro il numero di minuti in cui la macchina è rimasta in funzione e restituisce la quantità di succo nella tazza dopo che la macchina è stata spenta.
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>
Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.