다음을 통해 공유


메서드

메서드는 형식과 연결된 함수입니다. 개체 지향 프로그래밍에서 메서드는 개체 및 형식의 기능과 동작을 노출하고 구현하는 데 사용됩니다.

구문

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

설명

이전 구문에서는 다양한 형식의 메서드 선언 및 정의를 볼 수 있습니다. 긴 메서드 본문에서 줄 바꿈은 등호(=)를 따르고 전체 메서드 본문은 들여쓰기됩니다.

모든 메서드 선언에 특성을 적용할 수 있습니다. 메서드 정의의 구문 앞에 있으며 일반적으로 별도의 줄에 나열됩니다. 자세한 내용은 특성을 참조하세요.

메서드를 표시 inline할 수 있습니다. inline에 대한 내용은 인라인 함수를 참조하세요.

인라인이 아닌 메서드는 형식 내에서 재귀적으로 사용할 수 있습니다. 키워드(keyword) 명시적으로 사용할 rec 필요가 없습니다.

인스턴스 메서드

인스턴스 메서드는 키워드(keyword) 자체 식별자와 마침표(.) 및 메서드 이름 및 매개 변수를 사용하여 선언 member 됩니다. 바인딩의 경우 let마찬가지로 매개 변수 목록은 패턴일 수 있습니다. 일반적으로 메서드 매개 변수를 튜플 형식으로 괄호로 묶습니다. 이는 메서드가 다른 .NET Framework 언어로 생성되는 경우 F#에 표시되는 방식입니다. 그러나 curried 양식(공백으로 구분된 매개 변수)도 일반적이며 다른 패턴도 지원됩니다.

다음 예제에서는 비 추상 인스턴스 메서드의 정의 및 사용을 보여 줍니다.

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

인스턴스 메서드 내에서 자체 식별자를 사용하여 let 바인딩을 사용하여 정의된 필드에 액세스하지 마세요. 다른 멤버 및 속성에 액세스할 때 자체 식별자를 사용합니다.

정적 메서드

키워드(keyword) static 인스턴스 없이 메서드를 호출할 수 있고 개체 인스턴스와 연결되지 않도록 지정하는 데 사용됩니다. 그렇지 않은 경우 메서드는 인스턴스 메서드입니다.

다음 섹션의 예제에서는 키워드(keyword) 선언 let 된 필드, 키워드(keyword) 사용하여 선언된 member 속성 멤버 및 키워드(keyword) 선언된 정적 메서드를 static 보여 있습니다.

다음 예제에서는 정적 메서드의 정의 및 사용을 보여 줍니다. 이러한 메서드 정의가 이전 섹션의 SomeType 클래스에 있다고 가정합니다.

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

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

추상 메서드 및 가상 메서드

이 키워드(keyword) abstract 메서드에 가상 디스패치 슬롯이 있고 클래스에 정의가 없을 수 있음을 나타냅니다. 가상 디스패치 슬롯은 런타임에 개체 지향 형식의 가상 함수 호출을 조회하는 데 사용되는 내부적으로 기본 있는 함수 테이블의 항목입니다. 가상 디스패치 메커니즘은 개체 지향 프로그래밍의 중요한 기능인 다형성을 구현하는 메커니즘입니다. 정의가 없는 추상 메서드가 하나 이상 있는 클래스는 추상 클래스입니다 . 즉, 해당 클래스의 인스턴스를 만들 수 없습니다. 추상 클래스에 대한 자세한 내용은 추상 클래스를 참조 하세요.

추상 메서드 선언에는 메서드 본문이 포함되지 않습니다. 대신 메서드 이름 뒤에 콜론(:) 및 메서드의 형식 서명이 잇습니다. 메서드의 형식 서명은 매개 변수 이름이 없는 경우를 제외하고 Visual Studio Code 편집기에서 메서드 이름 위에 마우스 포인터를 일시 중지할 때 IntelliSense에서 보여 주는 것과 동일합니다. 형식 서명은 대화형으로 작업할 때 인터프리터 fsi.exe 표시됩니다. 메서드의 형식 시그니처는 매개 변수 형식을 나열한 다음 반환 형식을 적절한 구분 기호로 나열하여 구성됩니다. Curried 매개 변수는 튜플 매개 변수로 -> 구분되고 튜플 매개 변수는 .로 구분 *됩니다. 반환 값은 항상 기호로 인수 -> 와 구분됩니다. 함수 형식이 매개 변수인 경우와 같이 복잡한 매개 변수를 그룹화하거나 튜플이 두 매개 변수가 아닌 단일 매개 변수로 처리되는 시기를 나타내는 데 괄호를 사용할 수 있습니다.

이 항목의 구문 블록에 표시된 것처럼 클래스에 정의를 추가하고 키워드(keyword) 사용하여 default 추상 메서드 기본 정의를 제공할 수도 있습니다. 동일한 클래스에 정의가 있는 추상 메서드는 다른 .NET Framework 언어의 가상 메서드와 동일합니다. 정의가 있는지 abstract 여부에 관계없이 키워드(keyword) 클래스에 대한 가상 함수 테이블에 새 디스패치 슬롯을 만듭니다.

기본 클래스가 추상 메서드를 구현하는지 여부에 관계없이 파생 클래스는 추상 메서드의 구현을 제공할 수 있습니다. 파생 클래스에서 추상 메서드를 구현하려면 파생 클래스 또는 default 키워드(keyword) 사용하는 override 것을 제외하고 파생 클래스에서 이름과 시그니처가 같은 메서드를 정의하고 메서드 본문을 제공합니다. 키워드(keyword) 정확히 같은 것을 의미합니다 overridedefault. 새 메서드가 기본 클래스 구현을 재정의하는 경우 사용합니다 override . 원래 추상 선언과 동일한 클래스에서 구현을 만들 때 사용합니다 default . 기본 클래스에서 abstract 추상으로 선언된 메서드를 구현하는 메서드에서 키워드(keyword) 사용하지 마세요.

다음 예제에서는 .NET Framework 가상 메서드 Rotate 와 동일한 기본 구현이 있는 추상 메서드를 보여 줍니다.

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

다음 예제에서는 기본 클래스 메서드를 재정의하는 파생 클래스를 보여 줍니다. 이 경우 재정의는 메서드가 아무 작업도 수행하지 않도록 동작을 변경합니다.

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

오버로드된 메서드

오버로드된 메서드는 지정된 형식에서 이름이 동일하지만 인수가 다른 메서드입니다. F#에서 선택적 인수는 일반적으로 오버로드된 메서드 대신 사용됩니다. 그러나 오버로드된 메서드는 인수가 튜플 형식이 아닌 튜플 형식인 경우 언어로 허용됩니다.

선택적 인수

F# 4.1부터 메서드에 기본 매개 변수 값이 있는 선택적 인수를 사용할 수도 있습니다. 이는 C# 코드와의 상호 운용을 용이하게 하기 위한 것입니다. 다음 예제에서는 구문을 보여 줍니다.

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

전달된 DefaultParameterValue 값은 입력 형식과 일치해야 합니다. 위의 샘플에서 이 샘플은 .입니다 int. 정수가 아닌 값을 DefaultParameterValue 전달하려고 하면 컴파일 오류가 발생합니다.

예: 속성 및 메서드

다음 예제에는 필드, 프라이빗 함수, 속성 및 정적 메서드의 예제가 있는 형식이 포함되어 있습니다.

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

참고 항목