Partager via


Méthodes (F#)

Une méthode est une fonction associée à un type. Dans la programmation orientée objet, des méthodes sont utilisées pour exposer et implémenter la fonctionnalité et le comportement d'objets et de types.

// Instance method definition.
[ attributes ]
member [inline] self-identifier.method-name parameter-list [ : return-type ]=
    method-body

// Static method definition.
[ attributes ]
static member [inline] method-name parameter-list [ : return-type ]=
    method-body

// Abstract method declaration or virtual dispatch slot.
[ attributes ]
abstract member self-identifier.method-name : type-signature

// Virtual method declaration and default implementation.
[ attributes ]
abstract member self-identifier.method-name : type-signature
[ attributes ]
default member self-identifier.method-name parameter-list[ : return-type ] =
    method-body

// Override of inherited virtual method.
[ attributes ]
override member self-identifier.method-name parameter-list [ : return-type ]=
    method-body

Notes

Dans la syntaxe précédente, vous pouvez voir les différentes formes de déclaration et de définition de méthode. Dans les corps de méthode plus longs, un saut de ligne suit le signe égal (=), et la totalité du corps de la méthode est mise en retrait.

Des attributs peuvent être appliqués à n'importe quelle déclaration de méthode. Ils précèdent la syntaxe pour la définition d'une méthode et sont généralement répertoriés sur une ligne distincte. Pour plus d'informations, consultez Attributs (F#).

Les méthodes peuvent être marquées comme étant inline. Pour plus d'informations sur inline, consultez Fonctions inline (F#).

Les méthodes non inline peuvent être utilisées de manière récursive dans le type ; il n'y a aucun besoin d'utiliser le mot clé rec explicitement.

Méthodes d'instance

Les méthodes d'instance sont déclarées avec le mot clé member et self-identifier, suivi d'un point (.) ainsi que du nom de la méthode et des paramètres. Comme c'est le cas avec les liaisons let, la parameter-list peut être un modèle. En général, vous mettez les paramètres de méthode entre parenthèses sous forme de tuple, ce qui correspond à la façon dont les méthodes apparaissent en F# lorsqu'elles sont créées dans d'autres langages .NET Framework. Toutefois, la forme curryfiée (paramètres séparés par des espaces) est aussi couramment employée, et d'autres modèles sont également pris en charge.

L'exemple suivant illustre la définition et l'utilisation d'une méthode d'instance non abstraite.

type SomeType(factor0: int) =
   let factor = factor0
   member this.SomeMethod(a, b, c) =
      (a + b + c) * factor

   member this.SomeOtherMethod(a, b, c) =
      this.SomeMethod(a, b, c) * factor

Dans les méthodes d'instance, n'utilisez pas l'auto-identificateur (self-identifier) pour accéder aux champs définis à l'aide de liaisons let. Utilisez l'auto-identificateur lorsque vous accédez à d'autres membres et propriétés.

Méthodes statiques

Le mot clé static est utilisé pour spécifier qu'une méthode peut être appelée sans instance et qu'elle n'est associée à aucune instance d'objet. Sinon, les méthodes sont des méthodes d'instance.

L'exemple dans la section suivante montre les champs déclarés avec le mot clé let, les membres de propriété déclarés avec le mot clé member, et une méthode statique déclarée avec le mot clé static.

L'exemple suivant illustre la définition et l'utilisation de méthodes statiques. Supposez que ces définitions de méthode se trouvent dans la classe SomeType dans la section précédente.

static member SomeStaticMethod(a, b, c) =
   (a + b + c)

static member SomeOtherStaticMethod(a, b, c) =
   SomeType.SomeStaticMethod(a, b, c) * 100

Méthodes virtuelles et abstraites

Le mot clé abstract indique qu'une méthode possède un emplacement de dispatch virtuel et qu'elle peut ne pas avoir de définition dans la classe. Un emplacement de dispatch virtuel est une entrée, dans une table de fonctions gérée en interne, qui est utilisée au moment de l'exécution pour rechercher des appels de fonction virtuelle dans un type orienté objet. Le mécanisme de dispatch virtuel est le mécanisme qui implémente le polymorphisme, une fonctionnalité importante de la programmation orientée objet. Une classe qui possède au moins une méthode abstraite sans définition est une classe abstraite, ce qui signifie qu'aucune instance de cette classe ne peut être créée. Pour plus d'informations sur les classes abstraites, consultez Classes abstraites (F#).

Les déclarations de méthode abstraite n'incluent pas de corps de méthode. Au lieu de cela, le nom de la méthode est suivi d'un signe deux-points (:) et d'une signature de type pour la méthode. La signature de type d'une méthode est la même que celle indiquée par IntelliSense lorsque vous pointez avec la souris sur un nom de méthode dans l'éditeur de code Visual Studio, à la différence près qu'il n'y a pas de noms de paramètre. Les signatures de type sont également affichées par l'interpréteur, fsi.exe, en cas de fonctionnement interactif. La signature de type d'une méthode est formée en répertoriant les types des paramètres, puis le type de retour, avec les symboles de séparateur appropriés. Les paramètres curryfiés sont séparés par -> et les paramètres de tuple sont séparés par *. La valeur de retour est toujours séparée des arguments par le symbole ->. Des parenthèses peuvent être utilisées pour grouper des paramètres complexes, par exemple lorsqu'un type de fonction est un paramètre, ou pour indiquer lorsqu'un tuple est traité en tant que paramètre unique et non comme deux paramètres.

Vous pouvez également attribuer des définitions par défaut à des méthodes abstraites en ajoutant la définition à la classe et en utilisant le mot clé default, comme indiqué dans le bloc de syntaxe dans cette rubrique. Une méthode abstraite qui a une définition dans la même classe équivaut à une méthode virtuelle dans d'autres langages .NET Framework. Qu'une définition existe ou non, le mot clé abstract crée un nouvel emplacement de dispatch dans la table de fonctions virtuelles pour la classe.

Qu'une classe de base implémente ou non ses méthodes abstraites, les classes dérivées peuvent fournir des implémentations de méthodes abstraites. Pour implémenter une méthode abstraite dans une classe dérivée, définissez une méthode qui a le même nom et la même signature dans la classe dérivée, mais utilisez le mot clé override ou default, et fournissez le corps de la méthode. Les mots clés override et default signifient la même chose. Utilisez override si la nouvelle méthode substitue une implémentation de classe de base ; utilisez default lorsque vous créez une implémentation dans la même classe que la déclaration abstraite d'origine. N'utilisez pas le mot clé abstract sur la méthode qui implémente la méthode déclarée abstraite dans la classe de base.

L'exemple suivant illustre une méthode abstraite Rotate qui a une implémentation par défaut, l'équivalent d'une méthode virtuelle .NET Framework.

type Ellipse(a0 : float, b0 : float, theta0 : float) =
    let mutable axis1 = a0
    let mutable axis2 = b0
    let mutable rotAngle = theta0
    abstract member Rotate: float -> unit
    default this.Rotate(delta : float) = rotAngle <- rotAngle + delta

L'exemple suivant illustre une classe dérivée qui substitue une méthode de classe de base. Dans ce cas, la substitution modifie le comportement de manière à ce que la méthode ne fasse rien.

type Circle(radius : float) =
    inherit Ellipse(radius, radius, 0.0)
     // Circles are invariant to rotation, so do nothing.
    override this.Rotate(_) = ()

Méthodes surchargées

Les méthodes surchargées sont des méthodes qui ont des noms identiques dans un type donné, mais qui ont des arguments différents. En F#, les arguments facultatifs sont généralement utilisés à la place de méthodes surchargées. Toutefois, les méthodes surchargées sont autorisées dans le langage, à condition que les arguments soient sous forme de tuple, et non sous forme curryfiée.

Exemple : propriétés et méthodes

L'exemple suivant contient un type avec des exemples de champs, des fonctions privées, des propriétés et une méthode statique.

type RectangleXY(x1 : float, y1: float, x2: float, y2: float) =
    // Field definitions.
    let height = y2 - y1
    let width = x2 - x1
    let area = height * width
    // Private functions.
    static let maxFloat (x: float) (y: float) =
      if x >= y then x else y
    static let minFloat (x: float) (y: float) =
      if x <= y then x else y
    // Properties.
    // Here, "this" is used as the self identifier,
    // but it can be any identifier.
    member this.X1 = x1
    member this.Y1 = y1
    member this.X2 = x2
    member this.Y2 = y2
    // A static method.
    static member intersection(rect1 : RectangleXY, rect2 : RectangleXY) =
       let x1 = maxFloat rect1.X1 rect2.X1
       let y1 = maxFloat rect1.Y1 rect2.Y1
       let x2 = minFloat rect1.X2 rect2.X2
       let y2 = minFloat rect1.Y2 rect2.Y2
       let result : RectangleXY option =
         if ( x2 > x1 && y2 > y1) then
           Some (RectangleXY(x1, y1, x2, y2))
         else
           None
       result

// Test code.
let testIntersection =
    let r1 = RectangleXY(10.0, 10.0, 20.0, 20.0)
    let r2 = RectangleXY(15.0, 15.0, 25.0, 25.0)
    let r3 : RectangleXY option = RectangleXY.intersection(r1, r2)
    match r3 with
    | Some(r3) -> printfn "Intersection rectangle: %f %f %f %f" r3.X1 r3.Y1 r3.X2 r3.Y2
    | None -> printfn "No intersection found."

testIntersection

Voir aussi

Concepts

Membres (F#)

Historique des modifications

Date

Historique

Motif

Avril 2011

A supprimé un modificateur intégré de la syntaxe des méthodes virtuelles.

Résolution des bogues de contenu.