penso che tu abbia il concetto sbagliato qui. Le classi in Ruby sono simili alle classi in Java, Smalltalk, C#, ... e tutti sono modelli per le loro istanze. Quindi la classe definisce la struttura e il comportamento se le sue istanze e le parti della struttura e il comportamento delle istanze delle sue sottoclassi ma non viceversa.
Quindi l'accesso diretto da una superclasse a una costante in una sottoclasse non è affatto possibile e questa è una buona cosa. Vedi sotto come risolverlo. Per le tue classi definite, le seguenti cose sono vere:
class Animal
definisce il metodo make_noise
.
- istanze di
class Animal
possono chiamare il metodo make_noise
.
class Dog
definisce la costante NOISE
con il suo valore.
- istanze di
Dog
e la classe Dog
può utilizzare la costante NOISE
.
Quello che non è possibile:
- istanze di
Animal
o la classe Animal
sé hanno accesso alle costanti della classe Dog
.
Si può rimediare con la seguente modifica:
class Animal
def make_noise
print Dog::NOISE
end
end
Ma questo è un cattivo stile, perché ora, la tua superclasse (che è un'astrazione su Dog
e altri animali) sa ormai qualcosa che appartiene a Dog
.
Una soluzione migliore sarebbe:
- Definire un metodo astratto nella classe
Animal
quali definisce che make_noise
occorre definire. Vedere la risposta https://stackoverflow.com/a/6792499/41540.
- Definisci di nuovo il metodo nelle tue classi concrete, ma ora con il riferimento alla costante.
Ma se uso una variabile di istanza, significa che ogni istanza della classe Dog dovrà memorizzare i dati di rumore, giusto? Il rumore non cambierà tra le istanze di Cani (cioè, i cani abbaiano sempre), ecco perché ho pensato a una costante di sottoclasse. Cosa ne pensi? – Tim
@Tim No, ogni istanza della classe Dog non memorizza quel valore. 'p Dog.new.instance_eval {@noise} # => nil' La singola istanza della' Class' che si chiama 'Dog' memorizza quel valore. Proprio come le istanze delle classi sono oggetti che possono avere variabili di istanza, quindi le classi stesse sono oggetti (istanze della classe Class) che possono avere le proprie variabili di istanza. – Phrogz
Ho aggiornato ulteriormente l'esempio per mostrare che queste sono proprietà di 'Dog' stesso, non proprietà di istanze di Dog. Si potrebbe anche cambiare 'attr_accessor' in' attr_reader' se si volesse rafforzare maggiormente la sua costanza. – Phrogz