Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A metódus egy típushoz társított függvény. Az objektumorientált programozásban metódusokat használnak az objektumok és típusok funkcióinak és viselkedésének feltárására és megvalósítására.
Szemantika
// 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 ]
Megjegyzések
Az előző szintaxisban a metódusdefiníciók és -definíciók különböző formái láthatók. Hosszabb metódustestekben a sortörés az egyenlőségjelet (=) követi, és a teljes metódustörzs be van húzva.
Az attribútumok bármilyen metódusdeklarációra alkalmazhatók. Ezek megelőzik a metódusdefiníció szintaxisát, és általában külön sorban szerepelnek. További információ: Attribútumok.
A metódusok jelölhetők inline. További információ: inlineBeágyazott függvények.
A nem beágyazott metódusok rekurzív módon használhatók a típuson belül; nincs szükség a kulcsszó explicit használatára rec .
Példány metódusai
A példánymetódusok kulcsszóval és member vannak deklarálva, amelyet egy pont (.) követ, valamint a metódus neve és paraméterei. A kötésekhez hasonlóan a letparaméterlista is lehet minta. A metódusparamétereket általában zárójelek közé kell helyeznie egy tetszetős formában, így jelennek meg a metódusok az F#-ban, amikor más .NET-keretrendszernyelveken jönnek létre. A curried form (szóközökkel elválasztott paraméterek) azonban szintén gyakoriak, és más minták is támogatottak.
Az alábbi példa egy nem absztrakt példánymetódus definícióját és használatát mutatja be.
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
A példánymódszereken belül ne használja az önazonosítót a kötések használatával let definiált mezők eléréséhez. Használja az önazonosítót más tagok és tulajdonságok elérésekor.
Statikus metódusok
A kulcsszó static azt határozza meg, hogy egy metódus példány nélkül hívható meg, és nincs objektumpéldányhoz társítva. Ellenkező esetben a metódusok példánymetenek.
A következő szakaszban látható példa a kulcsszóval deklarált mezőket, a letmember kulcsszóval deklarált tulajdonságtagokat és a static kulcsszóval deklarált statikus metódust mutatja be.
Az alábbi példa a statikus metódusok definícióját és használatát mutatja be. Tegyük fel, hogy ezek a metódusdefiníciók az SomeType előző szakaszban szereplő osztályban találhatók.
static member SomeStaticMethod(a, b, c) =
(a + b + c)
static member SomeOtherStaticMethod(a, b, c) =
SomeType.SomeStaticMethod(a, b, c) * 100
Absztrakt és virtuális metódusok
A kulcsszó abstract azt jelzi, hogy egy metódus rendelkezik egy virtuális diszpécser ponttal, és lehet, hogy nincs definíciója az osztályban. A virtuális küldési pont egy belsőleg karbantartott függvénytáblában található bejegyzés, amelyet futásidőben használnak a virtuális függvényhívások objektumorientált típusban való kereséséhez. A virtuális küldési mechanizmus a polimorfizmust megvalósító mechanizmus, amely az objektumorientált programozás fontos funkciója. A definíció nélküli legalább egy absztrakt metódussal rendelkező osztály absztrakt osztály, ami azt jelenti, hogy az osztályból nem hozhatók létre példányok. Az absztrakt osztályokról további információt az Absztrakt osztályok című témakörben talál.
Az absztrakt metódus deklarációi nem tartalmaznak metódustörzset. Ehelyett a metódus nevét kettőspont (:) és a metódus típusadakta követi. A metódus típusaláírása megegyezik az IntelliSense által megjelenítettvel, amikor az egérmutatót a Visual Studio Code Editorban egy metódusnév fölé szünetelteti, kivéve a paraméternevek nélkül. A gépi aláírásokat az értelmező is megjeleníti, fsi.exe, amikor interaktívan dolgozik. A metódus típusaadéka a paraméterek típusainak felsorolásával, majd a visszatérési típussal, a megfelelő elválasztó szimbólumokkal. A curried paramétereket a rendszer elkülöníti, -> a rekordparamétereket pedig a *. A visszatérési értéket mindig szimbólum választja -> el az argumentumoktól. A zárójelek összetett paraméterek csoportosítására használhatók, például ha egy függvénytípus paraméter, vagy azt jelzi, hogy egy rekordot a rendszer két paraméter helyett egyetlen paraméterként kezel.
Az absztrakt metódusok alapértelmezett definícióit úgy is megadhatja, hogy hozzáadja a definíciót az osztályhoz, és használja a default kulcsszót, ahogyan az a jelen témakör szintaxisblokkjában látható. Az ugyanabban az osztályban definiált absztrakt metódus egyenértékű más .NET-keretrendszernyelvek virtuális metódusaival. Függetlenül attól, hogy létezik-e definíció, a abstract kulcsszó létrehoz egy új küldési pontot az osztály virtuális függvénytáblájában.
Függetlenül attól, hogy egy alaposztály implementálja-e az absztrakt metódusait, a származtatott osztályok absztrakciós módszerek implementálását is biztosíthatják. Ha absztrakt metódust szeretne implementálni egy származtatott osztályban, definiáljon egy metódust, amelynek neve és aláírása azonos a származtatott osztályban, kivéve a kulcsszót vagy override a kulcsszótdefault, és adja meg a metódus törzsét. A kulcsszavak override és default azt jelenti, pontosan ugyanazt a dolgot. Akkor használja override , ha az új metódus felülír egy alaposztály-implementációt; akkor használja default , ha az eredeti absztrakt deklarációval azonos osztályban hoz létre implementációt. Ne használja a kulcsszót abstract azon a metóduson, amely az alaposztályban absztraktként deklarált metódust implementálja.
Az alábbi példa egy olyan absztrakt metódust Rotate mutat be, amely alapértelmezett implementációval rendelkezik, amely a .NET-keretrendszer virtuális metódusának felel meg.
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
Az alábbi példa egy olyan származtatott osztályt mutat be, amely felülír egy alaposztály-metódust. Ebben az esetben a felülbírálás megváltoztatja a viselkedést, így a metódus nem tesz semmit.
type Circle(radius: float) =
inherit Ellipse(radius, radius, 0.0)
// Circles are invariant to rotation, so do nothing.
override this.Rotate(_) = ()
Túlterhelt metódusok
A túlterhelt metódusok olyan metódusok, amelyek azonos nevűek egy adott típusban, de eltérő argumentumokkal rendelkeznek. Az F#-ban a választható argumentumok általában túlterhelt metódusok helyett használatosak. A túlterhelt metódusok azonban megengedettek a nyelvben, feltéve, hogy az argumentumok gördült formában vannak, nem pedig curried formában. Az alábbi példa a következőket mutatja be:
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!
Választható argumentumok
Az F# támogatja a metódusok választható argumentumait. Az F#-ban elérhető választható argumentumok különböző formáival kapcsolatos részletes információkért lásd: Választható paraméterek.
Példa: Tulajdonságok és metódusok
Az alábbi példa olyan típust tartalmaz, amely példákat tartalmaz mezőkre, privát függvényekre, tulajdonságokra és statikus metódusokra.
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