Yöntemler
Yöntem, bir türle ilişkilendirilmiş bir işlevdir. Nesne odaklı programlamada yöntemler, nesnelerin ve türlerin işlevselliğini ve davranışını ortaya çıkarmak ve uygulamak için kullanılır.
Sözdizimi
// 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 ]
Açıklamalar
Önceki söz diziminde, yöntem bildirimlerinin ve tanımlarının çeşitli biçimlerini görebilirsiniz. Daha uzun yöntem gövdelerinde, eşittir işaretini (=) izleyen bir satır sonu olur ve tüm yöntem gövdesi girintilenir.
Öznitelikler herhangi bir yöntem bildirimine uygulanabilir. Bunlar, yöntem tanımının söz diziminin önünde yer alır ve genellikle ayrı bir satırda listelenir. Daha fazla bilgi için bkz . Öznitelikler.
Yöntemler olarak işaretlenebilir inline
. hakkında inline
bilgi için bkz . Satır içi İşlevler.
Satır içi olmayan yöntemler türü içinde özyinelemeli olarak kullanılabilir; anahtar sözcüğünü rec
açıkça kullanmanıza gerek yoktur.
Örnek Yöntemleri
Örnek yöntemleri anahtar sözcük ve kendi tanımlayıcısı member
ile bildirilir, ardından nokta (.) ve yöntem adı ve parametreleri gelir. Bağlamalar için let
olduğu gibi parametre listesi de bir desen olabilir. Genellikle yöntem parametrelerini bir tanımlama grubu biçiminde parantez içine alırsınız. Bu, yöntemlerin diğer .NET Framework dillerinde oluşturulduğunda F# dilinde görünme şeklidir. Bununla birlikte, curried formu (boşluklarla ayrılmış parametreler) de yaygındır ve diğer desenler de desteklenir.
Aşağıdaki örnekte soyut olmayan bir örnek yönteminin tanımı ve kullanımı gösterilmektedir.
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
Örnek yöntemlerinde, let bağlamalarını kullanarak tanımlanan alanlara erişmek için kendi tanımlayıcısını kullanmayın. Diğer üyelere ve özelliklere erişirken kendi tanımlayıcısını kullanın.
Statik Yöntemler
anahtar sözcüğü static
, bir yöntemin bir örnek olmadan çağrılabileceğini ve bir nesne örneğiyle ilişkilendirilmediğini belirtmek için kullanılır. Aksi takdirde, yöntemler örnek yöntemleridir.
Sonraki bölümdeki örnekte anahtar sözcükle bildirilen alanlar, anahtar sözcükle let
bildirilen özellik üyeleri ve anahtar sözcükle member
bildirilen statik bir yöntem gösterilmektedir static
.
Aşağıdaki örnekte statik yöntemlerin tanımı ve kullanımı gösterilmektedir. Bu yöntem tanımlarının önceki bölümdeki SomeType
sınıfında olduğunu varsayalım.
static member SomeStaticMethod(a, b, c) =
(a + b + c)
static member SomeOtherStaticMethod(a, b, c) =
SomeType.SomeStaticMethod(a, b, c) * 100
Soyut ve Sanal Yöntemler
anahtar sözcüğü abstract
, bir yöntemin sanal dağıtım yuvasına sahip olduğunu ve sınıfında bir tanımı olmayabilir. Sanal dağıtım yuvası, nesne odaklı bir türdeki sanal işlev çağrılarını aramak için çalışma zamanında kullanılan dahili bakımlı bir işlev tablosundaki bir giriştir. Sanal gönderim mekanizması, nesne odaklı programlamanın önemli bir özelliği olan polimorfizmi uygulayan mekanizmadır. Tanımı olmayan en az bir soyut yöntemi olan sınıf soyut bir sınıftır ve bu da o sınıftan hiçbir örneğin oluşturulamayacağı anlamına gelir. Soyut sınıflar hakkında daha fazla bilgi için bkz . Soyut Sınıflar.
Soyut yöntem bildirimleri bir yöntem gövdesi içermez. Bunun yerine, yönteminin adını iki nokta üst üste (:) ve yöntem için bir tür imzası) izler. Bir yöntemin tür imzası, parametre adları olmadan fare işaretçisini Visual Studio Code Düzenleyicisi'nde bir yöntem adının üzerinde duraklattığınızda IntelliSense tarafından gösterilen imzayla aynıdır. Tür imzaları, etkileşimli çalışırken yorumlayıcı fsi.exe tarafından da görüntülenir. Bir yöntemin tür imzası, parametre türlerinin listelenmesi ve ardından uygun ayırıcı sembollerle dönüş türü girilerek oluşturulur. Curried parametreleri ile ->
ayrılır ve tanımlama grubu parametreleri ile *
ayrılır. Dönüş değeri bağımsız değişkenlerden her zaman bir ->
simgeyle ayrılır. Parantezler, işlev türünün parametre olduğu durumlar gibi karmaşık parametreleri gruplandırmak veya tanımlama grubunun iki parametre yerine tek bir parametre olarak ele alınacağı durumları belirtmek için kullanılabilir.
Bu konudaki söz dizimi bloğunda gösterildiği gibi, tanımı sınıfa ekleyerek ve anahtar sözcüğünü default
kullanarak soyut yöntemlere varsayılan tanımlar da verebilirsiniz. Aynı sınıfta tanımı olan soyut bir yöntem, diğer .NET Framework dillerindeki sanal yöntemle eşdeğerdir. Bir tanımın abstract
mevcut olup olmadığı anahtar sözcüğü, sınıfı için sanal işlev tablosunda yeni bir dağıtım yuvası oluşturur.
Temel sınıfın kendi soyut yöntemlerini uygulayıp uygulamadığına bakılmaksızın, türetilmiş sınıflar soyut yöntemlerin uygulamalarını sağlayabilir. Türetilmiş bir sınıfta soyut bir yöntem uygulamak için, veya default
anahtar sözcüğünü kullanmak dışında türetilmiş sınıfta aynı ada ve imzaya override
sahip bir yöntem tanımlayın ve yöntem gövdesini sağlayın. Anahtar sözcükler ve default
anlamları override
tam olarak aynı anlama gelir. override
Yeni yöntem bir temel sınıf uygulamasını geçersiz kılarsa kullanın; özgün soyut bildirimle aynı sınıfta bir uygulama oluşturduğunuzda kullanındefault
. Temel sınıfta soyut olarak bildirilen yöntemi uygulayan yönteminde anahtar sözcüğünü kullanmayın abstract
.
Aşağıdaki örnekte, .NET Framework sanal yönteminin Rotate
eşdeğeri olan varsayılan bir uygulamaya sahip soyut bir yöntem gösterilmektedir.
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
Aşağıdaki örnekte, temel sınıf yöntemini geçersiz kılan türetilmiş bir sınıf gösterilmektedir. Bu durumda, geçersiz kılma yöntemi hiçbir şey yapmaz şekilde davranışı değiştirir.
type Circle(radius: float) =
inherit Ellipse(radius, radius, 0.0)
// Circles are invariant to rotation, so do nothing.
override this.Rotate(_) = ()
Aşırı Yüklenmiş Yöntemler
Aşırı yüklenmiş yöntemler, belirli bir türde aynı adlara sahip olan ancak farklı bağımsız değişkenlere sahip yöntemlerdir. F# dilinde, isteğe bağlı bağımsız değişkenler genellikle aşırı yüklenmiş yöntemler yerine kullanılır. Ancak, bağımsız değişkenlerin curried biçiminde değil tanımlama grubu biçiminde olması koşuluyla, dilde aşırı yüklenmiş yöntemlere izin verilir.
İsteğe Bağlı Bağımsız Değişkenler
F# 4.1'den başlayarak, yöntemlerde varsayılan parametre değerine sahip isteğe bağlı bağımsız değişkenlere de sahip olabilirsiniz. Bu, C# koduyla birlikte çalışabilirliği kolaylaştırmaya yardımcı olmaktır. Aşağıdaki örnekte söz dizimi gösterilmektedir:
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
için DefaultParameterValue
geçirilen değerin giriş türüyle eşleşmesi gerektiğini unutmayın. Yukarıdaki örnekte bir int
'dir. içine tamsayı olmayan bir değer DefaultParameterValue
geçirme girişimi derleme hatasına neden olur.
Örnek: Özellikler ve Yöntemler
Aşağıdaki örnek, alan örnekleri, özel işlevler, özellikler ve statik bir yöntem içeren bir tür içerir.
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