Les classes dans Swift peuvent appeler et accéder aux méthodes, propriétés et indices appartenant à leur superclasse et peuvent fournir leurs propres versions de remplacement de ces méthodes, propriétés et indices pour affiner ou modifier leur comportement.
Toute classe qui n'hérite pas d'une autre classe est appelée classe de base.
L'exemple ci-dessous définit une classe de base appelée Vehicle. Cette classe de base définit une propriété stockée appelée currentSpeed, avec une valeur par défaut de 0.0 (en déduisant un type de propriété de Double). La valeur de la propriété currentSpeed est utilisée par une propriété calculée String en lecture seule appelée description pour créer une description du véhicule.
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing - an arbitrary vehicle doesn't make a noise
}
}
Vous créez une nouvelle instance de Vehicle avec la syntaxe d'initialisation :
let someVehicle = Vehicle()
print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
La classe Vehicle définit des caractéristiques communes pour un véhicule arbitraire
Sous-classe ou classe fille
Le sous-classement consiste à baser une nouvelle classe sur une classe existante. La sous-classe hérite des caractéristiques de la classe existante, que vous pouvez ensuite affiner. Vous pouvez également ajouter de nouvelles caractéristiques à la sous-classe.
Pour indiquer qu'une sous-classe a une superclasse, écrivez le nom de la sous-classe avant le nom de la superclasse, séparé par deux points :
class SousClass: SuperClasse {
// subclass definition goes here
}
L'exemple suivant définit une sous-classe appelée Bicycle, avec une superclasse de Vehicle :
class Bicycle: Vehicle {
var hasBasket = false
}
La nouvelle classe Bicycle gagne automatiquement toutes les caractéristiques de Vehicle, comme ses propriétés currentSpeed et description et sa méthode makeNoise().
En plus des caractéristiques dont elle hérite, la classe Bicycle définit une nouvelle propriété stockée, hasBasket, avec une valeur par défaut de false (déduire un type de Bool pour la propriété).
Vous pouvez également modifier la propriété currentSpeed héritée d'une instance Bicycle et interroger la propriété description héritée de l'instance :
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
Les sous-classes peuvent elles-mêmes être sous-classées. L'exemple suivant crée une sous-classe de Bicycle pour un vélo biplace appelé "tandem" :
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
Tandem hérite de toutes les propriétés et méthodes de Bicycle, qui à son tour hérite de toutes les propriétés et méthodes de Vehicle :
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour
Les propriétés
Pour remplacer une caractéristique qui serait autrement héritée, vous préfixez votre définition de remplacement avec le mot-clé override. Cela précise que vous avez l'intention de fournir un remplacement et que vous n'avez pas fourni de définition correspondante par erreur. Le remplacement accidentel peut entraîner un comportement inattendu et tout remplacement sans le mot-clé override est diagnostiqué comme une erreur lors de la compilation de votre code.
Lorsque cela est approprié, vous accédez à la version superclasse d'une méthode, d'une propriété ou d'un indice en utilisant le préfixe super :
Une méthode substituée nommée someMethod() peut appeler la version de la superclasse de someMethod() en appelant super.someMethod() dans l'implémentation de la méthode de substitution.
Une propriété substituée appelée someProperty peut accéder à la version de la superclasse de someProperty comme super.someProperty dans l'implémentation du getter ou du setter de substitution.
Un indice remplacé pour someIndex peut accéder à la version superclasse du même indice super[someIndex] à partir de l'implémentation d'indice de remplacement.
Les méthodes
L'exemple suivant définit une nouvelle sous-classe de Vehicle appelé Train, qui remplace la méthode makeNoise() dont Train hérite de Vehicle :
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
Remplacer une méthode
Vous pouvez remplacer une propriété d'instance ou de type héritée pour fournir votre propre getter et setter personnalisés pour cette propriété, ou pour ajouter des observateurs de propriétés pour permettre à la propriété de remplacement d'observer quand la valeur de propriété sous-jacente change.
Vous pouvez présenter une propriété en lecture seule héritée en tant que propriété en lecture-écriture en fournissant à la fois un getter et un setter dans votre remplacement de propriété de sous-classe. Cependant, vous ne pouvez pas présenter une propriété en lecture-écriture héritée en tant que propriété en lecture seule.
L'exemple suivant définit une nouvelle classe appelée Car, qui est une sous-classe de Vehicle. La classe Car introduit une nouvelle propriété stockée appelée gear, avec une valeur entière par défaut de 1. La classe Car remplace également la propriété description dont elle hérite de Vehicle, pour fournir une description personnalisée qui inclut l'équipement actuel :
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
Vous pouvez utiliser le remplacement de propriété pour ajouter des observateurs de propriétés à une propriété héritée. Cela vous permet d'être averti lorsque la valeur d'une propriété héritée change, quelle que soit la manière dont cette propriété a été implémentée à l'origine.
Vous ne pouvez pas ajouter d'observateurs de propriétés à des propriétés stockées constantes héritées ou à des propriétés calculées en lecture seule héritées.
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
Empêcher les remplacements
Vous pouvez empêcher une méthode, une propriété ou un indice d'être remplacé en le marquant comme final. Pour ce faire , en écrivant le modificateur avant le mot-clé final introducteur de la méthode, la propriété ou de l'indice ( par exemple final var, final func, final class, final subscript).
Vous pouvez marquer une classe entière comme finale en écrivant le modificateur final avant le mot-clé class dans sa définition de classe (final class). Toute tentative de sous-classe d'une classe finale est signalée comme une erreur de compilation.