Bagikan melalui


Metode

Metode adalah fungsi yang terkait dengan jenis. Dalam pemrograman berorientasi objek, metode digunakan untuk mengekspos dan mengimplementasikan fungsionalitas dan perilaku objek dan jenis.

Sintaksis

// 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 ]

Komentar

Dalam sintaks sebelumnya, Anda dapat melihat berbagai bentuk deklarasi dan definisi metode. Dalam badan metode yang lebih panjang, pemisah baris mengikuti tanda sama dengan (=), dan seluruh isi metode diinden.

Atribut dapat diterapkan ke deklarasi metode apa pun. Mereka mendahului sintaks untuk definisi metode dan biasanya tercantum pada baris terpisah. Untuk informasi selengkapnya, lihat atribut .

Metode dapat ditandai inline. Untuk informasi tentang inline, lihat Fungsi Sebaris.

Metode non-sebaris dapat digunakan secara rekursif dalam jenis; tidak perlu menggunakan rec kata kunci secara eksplisit.

Metode instans

Metode instans dinyatakan dengan member kata kunci dan pengidentifikasi diri, diikuti dengan titik (.) dan nama metode dan parameter. Seperti halnya pengikatan let , daftar parameter dapat menjadi pola. Biasanya, Anda mengapit parameter metode dalam tanda kurung dalam bentuk tuple, yang merupakan cara metode muncul di F# ketika dibuat dalam bahasa .NET Framework lainnya. Namun, bentuk kurir (parameter yang dipisahkan oleh spasi) juga umum, dan pola lain juga didukung.

Contoh berikut mengilustrasikan definisi dan penggunaan metode instans non-abstrak.

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

Dalam metode instans, jangan gunakan pengidentifikasi mandiri untuk mengakses bidang yang ditentukan dengan menggunakan let pengikatan. Gunakan pengidentifikasi mandiri saat mengakses anggota dan properti lain.

Metode statis

Kata kunci static digunakan untuk menentukan bahwa metode dapat dipanggil tanpa instans dan tidak terkait dengan instans objek. Jika tidak, metode adalah metode instans.

Contoh di bagian berikutnya menunjukkan bidang yang dideklarasikan dengan let kata kunci, anggota properti yang dideklarasikan dengan member kata kunci, dan metode statis yang dideklarasikan dengan static kata kunci.

Contoh berikut mengilustrasikan definisi dan penggunaan metode statis. Asumsikan bahwa definisi metode ini ada di SomeType kelas di bagian sebelumnya.

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

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

Metode abstrak dan virtual

Kata kunci abstract menunjukkan bahwa metode memiliki slot pengiriman virtual dan mungkin tidak memiliki definisi di kelas . Slot pengiriman virtual adalah entri dalam tabel fungsi yang dikelola secara internal yang digunakan pada waktu proses untuk mencari panggilan fungsi virtual dalam jenis berorientasi objek. Mekanisme pengiriman virtual adalah mekanisme yang menerapkan polimorfisme, fitur penting dari pemrograman berorientasi objek. Kelas yang memiliki setidaknya satu metode abstrak tanpa definisi adalah kelas abstrak, yang berarti bahwa tidak ada instans yang dapat dibuat dari kelas tersebut. Untuk informasi selengkapnya tentang kelas abstrak, lihat Kelas Abstrak.

Deklarasi metode abstrak tidak menyertakan isi metode. Sebagai gantinya, nama metode diikuti oleh titik dua (:) dan tanda tangan jenis untuk metode tersebut. Tanda tangan jenis metode sama dengan yang ditunjukkan oleh IntelliSense saat Anda menjeda penunjuk mouse di atas nama metode di Editor Visual Studio Code, kecuali tanpa nama parameter. Tanda tangan jenis juga ditampilkan oleh penerjemah, fsi.exe, saat Anda bekerja secara interaktif. Tanda tangan jenis metode dibentuk dengan mencantumkan jenis parameter, diikuti dengan jenis pengembalian, dengan simbol pemisah yang sesuai. Parameter kurir dipisahkan oleh -> dan parameter tuple dipisahkan oleh *. Nilai yang dikembalikan selalu dipisahkan dari argumen dengan -> simbol. Tanda kurung dapat digunakan untuk mengelompokkan parameter kompleks, seperti ketika jenis fungsi adalah parameter, atau untuk menunjukkan kapan tuple diperlakukan sebagai parameter tunggal daripada sebagai dua parameter.

Anda juga dapat memberikan definisi default metode abstrak dengan menambahkan definisi ke kelas dan menggunakan default kata kunci, seperti yang ditunjukkan dalam blok sintaks dalam topik ini. Metode abstrak yang memiliki definisi di kelas yang sama setara dengan metode virtual dalam bahasa .NET Framework lainnya. Apakah ada definisi atau tidak, abstract kata kunci membuat slot pengiriman baru di tabel fungsi virtual untuk kelas .

Terlepas dari apakah kelas dasar mengimplementasikan metode abstraknya, kelas turunan dapat memberikan implementasi metode abstrak. Untuk menerapkan metode abstrak di kelas turunan, tentukan metode yang memiliki nama dan tanda tangan yang sama di kelas turunan, kecuali gunakan override kata kunci atau default , dan berikan isi metode. Kata kunci override dan default berarti hal yang sama persis. Gunakan override jika metode baru mengambil alih implementasi kelas dasar; gunakan default saat Anda membuat implementasi di kelas yang sama dengan deklarasi abstrak asli. Jangan gunakan abstract kata kunci pada metode yang mengimplementasikan metode yang dinyatakan abstrak di kelas dasar.

Contoh berikut mengilustrasikan metode Rotate abstrak yang memiliki implementasi default, setara dengan metode virtual .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

Contoh berikut mengilustrasikan kelas turunan yang mengambil alih metode kelas dasar. Dalam hal ini, penimpaan mengubah perilaku sehingga metode tidak melakukan apa pun.

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

Metode kelebihan beban

Metode yang kelebihan beban adalah metode yang memiliki nama identik dalam jenis tertentu tetapi memiliki argumen yang berbeda. Di F#, argumen opsional biasanya digunakan alih-alih metode yang kelebihan beban. Namun, metode kelebihan beban diizinkan dalam bahasa, asalkan argumen dalam bentuk tuple, bukan bentuk kurir. Contoh berikut menunjukkannya:

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!

Argumen opsional

F# mendukung argumen opsional untuk metode. Untuk informasi terperinci tentang berbagai bentuk argumen opsional yang tersedia di F#, lihat Parameter opsional.

Contoh: Properti dan metode

Contoh berikut berisi jenis yang memiliki contoh bidang, fungsi privat, properti, dan metode statis.

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

Lihat juga