Metody

Metoda je funkce přidružená k typu. V objektově orientovaném programování se metody používají k zveřejnění a implementaci funkcí a chování objektů a typů.

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 ]

Poznámky

V předchozí syntaxi můžete vidět různé formy deklarací a definic metod. V delších tělech metody se konec řádku řídí znaménkem rovná se (=) a celý text metody je odsazený.

Atributy lze použít pro jakoukoli deklaraci metody. Před syntaxí definice metody a obvykle jsou uvedeny na samostatném řádku. Další informace naleznete v tématu Atributy.

Metody lze označit inline. Informace o inlinefunkci Inline Functions naleznete v tématu Vložené funkce.

Neline metody lze použít rekurzivně v rámci typu; není nutné explicitně používat rec klíčové slovo.

Metody instance

Metody instance jsou deklarovány pomocí klíčového member slova a identifikátoru sebe, za kterým následuje tečka (.) a název a parametry metody. Stejně jako u let vazeb může být seznam parametrů vzorem. Parametry metody obvykle uzavřete do závorek ve formuláři řazené kolekce členů, což je způsob, jakým se metody zobrazují v jazyce F# při jejich vytváření v jiných jazycích rozhraní .NET Framework. Složený formulář (parametry oddělené mezerami) je ale také běžný a podporují se také jiné vzory.

Následující příklad znázorňuje definici a použití ne abstraktní metody instance.

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

V rámci metod instance nepoužívejte identifikátor sebeobsadu pro přístup k polím definovaným pomocí vazeb let. Při přístupu k ostatním členům a vlastnostem použijte identifikátor sebe sama.

Statické metody

Klíčové slovo static se používá k určení, že metodu lze volat bez instance a není přidružena k instanci objektu. V opačném případě jsou metody instance.

Příklad v další části zobrazuje pole deklarovaná klíčovým slovem let , členy vlastností deklarované pomocí member klíčového slova a statickou metodu deklarovanou pomocí klíčového static slova.

Následující příklad znázorňuje definici a použití statických metod. Předpokládejme, že tyto definice metody jsou ve SomeType třídě v předchozí části.

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

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

Abstraktní a virtuální metody

Klíčové slovo abstract označuje, že metoda má virtuální dispečer slot a nemusí mít definici ve třídě. Virtuální slot dispečinku je položka v interně udržované tabulce funkcí, která se používá za běhu k vyhledání volání virtuálních funkcí v objektově orientovaném typu. Virtuální mechanismus odesílání je mechanismus, který implementuje polymorfismus, důležitou funkcí objektově orientovaného programování. Třída, která má alespoň jednu abstraktní metodu bez definice, je abstraktní třída, což znamená, že nelze vytvořit žádné instance této třídy. Další informace o abstraktních třídách naleznete v tématu Abstraktní třídy.

Deklarace abstraktní metody neobsahují tělo metody. Místo toho za názvem metody následuje dvojtečka (:) a podpis typu metody. Podpis typu metody je stejný jako při pozastavení ukazatele myši nad názvem metody v Editoru editoru visual studio code s výjimkou bez názvů parametrů. Podpisy typu se také zobrazují interpretem, fsi.exe, když pracujete interaktivně. Podpis typu metody je vytvořen výpisem typů parametrů následovaných návratovým typem s odpovídajícími symboly oddělovače. Curried parameters are separated by -> and tuple parameters are separated by *. Vrácená hodnota je vždy oddělena od argumentů -> symbolem. Závorky lze použít k seskupení složitých parametrů, jako je například typ funkce, nebo k označení, kdy je řazená kolekce členů považována za jeden parametr, a ne jako dva parametry.

Můžete také poskytnout abstraktní metody výchozí definice přidáním definice do třídy a pomocí klíčového default slova, jak je znázorněno v bloku syntaxe v tomto tématu. Abstraktní metoda, která má definici ve stejné třídě, je ekvivalentní virtuální metodě v jiných jazycích rozhraní .NET Framework. Bez ohledu na to, zda definice existuje, abstract klíčové slovo vytvoří nový slot dispatch ve virtuální tabulce funkcí pro třídu.

Bez ohledu na to, zda základní třída implementuje své abstraktní metody, odvozené třídy mohou poskytovat implementace abstraktních metod. Chcete-li implementovat abstraktní metodu v odvozené třídě, definujte metodu se stejným názvem a podpisem v odvozené třídě, s výjimkou použití override nebo default klíčového slova, a zadejte tělo metody. Klíčová slova override a default přesně to znamená totéž. Použijte override , pokud nová metoda přepíše implementaci základní třídy; používá default se při vytváření implementace ve stejné třídě jako původní abstraktní deklarace. Nepoužívejte abstract klíčové slovo pro metodu, která implementuje metodu deklarovanou abstraktní v základní třídě.

Následující příklad znázorňuje abstraktní metodu Rotate , která má výchozí implementaci, což je ekvivalent virtuální metody rozhraní .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

Následující příklad znázorňuje odvozenou třídu, která přepíše metodu základní třídy. V tomto případě přepsání změní chování tak, aby metoda nic neudělala.

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

Přetížené metody

Přetížené metody jsou metody, které mají identické názvy v daném typu, ale mají různé argumenty. V jazyce F# se volitelné argumenty obvykle používají místo přetížených metod. Přetížené metody jsou však povoleny v jazyce za předpokladu, že argumenty jsou ve formě řazené kolekce členů, nikoli vytvrzené formuláře.

Volitelné argumenty

Počínaje jazykem F# 4.1 můžete mít také volitelné argumenty s výchozí hodnotou parametru v metodách. To vám pomůže usnadnit spolupráci s kódem jazyka C#. Následující příklad ukazuje syntaxi:

open System.Runtime.InteropServices
// A class with a method M, which takes in an optional integer argument.
type C() =
    member _.M([<Optional; DefaultParameterValue(12)>] i) = i + 1

Všimněte si, že hodnota předaná pro DefaultParameterValue musí odpovídat vstupnímu typu. Ve výše uvedeném vzorku je to .int Při pokusu o předání celočíselné hodnoty by DefaultParameterValue došlo k chybě kompilace.

Příklad: Vlastnosti a metody

Následující příklad obsahuje typ, který obsahuje příklady polí, privátních funkcí, vlastností a statické metody.

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

Viz také