Partager via


Méthodes

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

Syntaxe

// 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 method-name : type-signature

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

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

// Optional and DefaultParameterValue attributes on input parameters
[ attributes ]
[ modifier ] member [inline] self-identifier.method-name ([<Optional; DefaultParameterValue( default-value )>] input) [ : return-type ]

Remarques

Dans la syntaxe précédente, vous pouvez voir les différentes formes de déclarations et définitions de méthode. Dans les corps de méthode plus longs, un saut de ligne suit le signe égal (=) et le corps de la méthode entière est mis en retrait.

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

Les méthodes peuvent être marquées inline. Pour plus d’informations sur inline, consultez Fonctions inline.

Les méthodes non incorporées peuvent être utilisées de manière récursive dans le type ; il n’est pas nécessaire d’utiliser explicitement le rec mot clé.

Méthodes d’instance

Les méthodes d’instance sont déclarées avec le member mot clé et un auto-identificateur, suivis d’un point (.) et du nom et des paramètres de la méthode. Comme c’est le cas pour let les liaisons, la liste de paramètres peut être un modèle. En règle générale, vous placez les paramètres de méthode entre parenthèses dans un formulaire tuple, c’est-à-dire la façon dont les méthodes apparaissent en F# lorsqu’elles sont créées dans d’autres langages .NET Framework. Toutefois, le formulaire curried (paramètres séparés par des espaces) est également courant, 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’identificateur automatique pour accéder aux champs définis à l’aide let de liaisons. Utilisez l’identificateur automatique lors de l’accès à 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 n’est pas associée à une instance d’objet. Sinon, les méthodes sont des méthodes d’instance.

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

L’exemple suivant illustre la définition et l’utilisation de méthodes statiques. Supposons que ces définitions de méthode se trouvent dans la SomeType classe de 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 abstraites et virtuelles

Le mot clé abstract indique qu’une méthode a un emplacement de répartition virtuel et qu’elle n’a peut-être pas de définition dans la classe. Un emplacement de répartition virtuelle 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 répartition virtuelle est le mécanisme qui implémente le polymorphisme, une caractéristique importante de la programmation orientée objet. Une classe qui a au moins une méthode abstraite sans définition est une classe abstraite, ce qui signifie qu’aucune instance ne peut être créée de cette classe. Pour plus d’informations sur les classes abstraites, consultez Classes abstraites.

Les déclarations de méthode abstraites 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 identique à celle affichée par IntelliSense lorsque vous suspendez le pointeur de la souris sur un nom de méthode dans Visual Studio Code Editor, sauf sans nom de paramètre. Les signatures de type sont également affichées par l’interpréteur, fsi.exe, lorsque vous travaillez de manière interactive. La signature de type d’une méthode est formée en listant les types des paramètres, suivis du type de retour, avec les symboles de séparateur appropriés. Les paramètres curried sont séparés par -> et les paramètres tuple sont séparés par *. La valeur de retour est toujours séparée des arguments par un -> symbole. Les parenthèses peuvent être utilisées pour regrouper des paramètres complexes, comme lorsqu’un type de fonction est un paramètre, ou pour indiquer quand un tuple est traité comme un paramètre unique plutôt que comme deux paramètres.

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

Qu’une classe de base implémente 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 portant le même nom et la même signature dans la classe dérivée, sauf utiliser le ou override le default mot clé et fournir le corps de la méthode. Les mots clés override et default signifient exactement la même chose. Utilisez override si la nouvelle méthode remplace une implémentation de classe de base ; utilisez-la default lorsque vous créez une implémentation dans la même classe que la déclaration abstraite d’origine. N’utilisez pas le abstract mot clé 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 Rotate abstraite 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 remplace une méthode de classe de base. Dans ce cas, le remplacement modifie le comportement afin 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. Dans F#, les arguments facultatifs sont généralement utilisés au lieu de méthodes surchargées. Toutefois, les méthodes surchargées sont autorisées dans la langue, à condition que les arguments soient sous forme tuple, et non sous forme curriée. L’exemple suivant le montre :

type MyType(dataIn: int) =
    let data = dataIn
    member this.DoSomething(a: int) = a + data
    member this.DoSomething(a: string) = sprintf "Hello world, %s!" a

let m = MyType(10)
printfn "With int: %d" (m.DoSomething(2)) // With int: 12
printfn "With string: %s" (m.DoSomething("Bill")) // With string: Hello world, Bill!

Arguments facultatifs

F# prend en charge les arguments facultatifs pour les méthodes. Pour plus d’informations sur les différentes formes d’arguments facultatifs disponibles dans F#, consultez paramètres facultatifs.

Exemple : Propriétés et méthodes

L’exemple suivant contient un type qui contient des exemples de champs, de fonctions privées, de propriétés et d’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