Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
L’héritage est utilisé pour modéliser la relation « is-a » ou la sous-saisie, dans la programmation orientée objet.
Spécification des relations d’héritage
Vous spécifiez des relations d’héritage à l’aide du inherit mot clé dans une déclaration de classe. Le formulaire syntactical de base est illustré dans l’exemple suivant.
type MyDerived(...) =
inherit MyBase(...)
Une classe peut avoir au plus une classe de base directe. Si vous ne spécifiez pas de classe de base à l’aide du inherit mot clé, la classe hérite implicitement de System.Object.
Membres hérités
Si une classe hérite d’une autre classe, les méthodes et les membres de la classe de base sont disponibles pour les utilisateurs de la classe dérivée comme s’ils étaient des membres directs de la classe dérivée.
Les liaisons let et les paramètres de constructeur sont privés à une classe et, par conséquent, ne peuvent pas être accessibles à partir de classes dérivées.
Le mot clé base est disponible dans les classes dérivées et fait référence à l’instance de classe de base. Il est utilisé comme l’auto-identificateur.
Méthodes virtuelles et remplacements
Les méthodes virtuelles (et les propriétés) fonctionnent légèrement différemment en F# par rapport à d’autres langages .NET. Pour déclarer un nouveau membre virtuel, vous utilisez le abstract mot clé. Vous effectuez cette opération, que vous fournissiez une implémentation par défaut pour cette méthode. Ainsi, une définition complète d’une méthode virtuelle dans une classe de base suit ce modèle :
abstract member [method-name] : [type]
default [self-identifier].[method-name] [argument-list] = [method-body]
Et dans une classe dérivée, une substitution de cette méthode virtuelle suit ce modèle :
override [self-identifier].[method-name] [argument-list] = [method-body]
Si vous omettez l’implémentation par défaut dans la classe de base, la classe de base devient une classe abstraite.
L’exemple de code suivant illustre la déclaration d’une nouvelle méthode function1 virtuelle dans une classe de base et comment la remplacer dans une classe dérivée.
type MyClassBase1() =
let mutable z = 0
abstract member function1: int -> int
default u.function1(a: int) =
z <- z + a
z
type MyClassDerived1() =
inherit MyClassBase1()
override u.function1(a: int) = a + 1
Constructeurs et héritage
Le constructeur de la classe de base doit être appelé dans la classe dérivée. Les arguments du constructeur de classe de base apparaissent dans la liste d’arguments de la clause inherit. Les valeurs utilisées doivent être déterminées à partir des arguments fournis au constructeur de classe dérivé.
Le code suivant montre une classe de base et une classe dérivée, où la classe dérivée appelle le constructeur de classe de base dans la clause hérite :
type MyClassBase2(x: int) =
let mutable z = x * x
do
for i in 1..z do
printf "%d " i
type MyClassDerived2(y: int) =
inherit MyClassBase2(y * 2)
do
for i in 1..y do
printf "%d " i
Dans le cas de plusieurs constructeurs, le code suivant peut être utilisé. La première ligne des constructeurs de classes dérivées est la inherit clause, et les champs apparaissent sous forme de champs explicites déclarés avec le val mot clé. Pour plus d’informations, consultez Champs explicites : le val mot clé.
type BaseClass =
val string1 : string
new (str) = { string1 = str }
new () = { string1 = "" }
type DerivedClass =
inherit BaseClass
val string2 : string
new (str1, str2) = { inherit BaseClass(str1); string2 = str2 }
new (str2) = { inherit BaseClass(); string2 = str2 }
let obj1 = DerivedClass("A", "B")
let obj2 = DerivedClass("A")
Alternatives à l’héritage
Dans les cas où une modification mineure d’un type est requise, envisagez d’utiliser une expression d’objet comme alternative à l’héritage. L’exemple suivant illustre l’utilisation d’une expression d’objet comme alternative à la création d’un nouveau type dérivé :
open System
let object1 =
{ new Object() with
override this.ToString() = "This overrides object.ToString()" }
printfn "%s" (object1.ToString())
Pour plus d’informations sur les expressions d’objet, consultez Expressions d’objet.
Lorsque vous créez des hiérarchies d’objets, envisagez d’utiliser une union discriminatoire au lieu de l’héritage. Les unions discriminatoires peuvent également modéliser différents comportements de différents objets qui partagent un type global commun. Une seule union discriminée peut souvent éliminer la nécessité d’un certain nombre de classes dérivées qui sont des variations mineures les unes des autres. Pour plus d’informations sur les syndicats discriminatoires, consultez Les syndicats discriminatoires.