클래스(F#)

클래스는 속성, 메서드 및 이벤트를 가질 수 있는 개체를 나타내는 형식입니다.

구문

// Class definition:
type [access-modifier] type-name [type-params] [access-modifier] ( parameter-list ) [ as identifier ] =
[ class ]
[ inherit base-type-name(base-constructor-args) ]
[ let-bindings ]
[ do-bindings ]
member-list
...
[ end ]
// Mutually recursive class definitions:
type [access-modifier] type-name1 ...
and [access-modifier] type-name2 ...
...

설명

클래스는 .NET 개체 형식에 대한 기본 설명을 나타냅니다. 클래스는 F#에서 개체 지향 프로그래밍을 지원하는 기본 형식 개념입니다.

위의 구문 type-name 에서 유효한 식별자입니다. 선택 type-params 적 제네릭 형식 매개 변수를 설명합니다. 형식 매개 변수 이름 및 제약 조건은 꺾쇠 괄호(<>)로 묶입니다. 자세한 내용은 제네릭제약 조건을 참조하세요. 생성 parameter-list 자 매개 변수를 설명합니다. 첫 번째 액세스 한정자는 형식과 관련이 있습니다. 두 번째는 주 생성자와 관련이 있습니다. 두 경우 모두 기본값은 .입니다 public.

키워드(keyword) 사용하여 클래스의 기본 클래스를 지정합니다 inherit . 기본 클래스 생성자에 대한 인수를 괄호로 제공해야 합니다.

바인딩을 사용하여 let 클래스에 로컬인 필드 또는 함수 값을 선언하고 바인딩에 대한 let 일반 규칙을 따라야 합니다. 이 섹션에는 do-bindings 개체 생성 시 실행할 코드가 포함되어 있습니다.

추가 member-list 생성자, 인스턴스 및 정적 메서드 선언, 인터페이스 선언, 추상 바인딩, 속성 및 이벤트 선언으로 구성됩니다. 멤버에 설명되어 있습니다.

선택적 as 키워드(keyword) 사용되는 항목은 identifier 형식 정의에서 형식의 인스턴스를 참조하는 데 사용할 수 있는 인스턴스 변수 또는 자체 식별자에 이름을 지정합니다. 자세한 내용은 이 항목의 뒷부분에 있는 자체 식별자 섹션을 참조하세요.

정의의 시작과 end 끝을 표시하는 키워드(keyword) class 선택 사항입니다.

상호 재귀적 형식인 상호 재귀 형식은 상호 재귀 함수와 and 마찬가지로 키워드(keyword) 함께 조인됩니다. 예를 들어 상호 재귀 형식 섹션을 참조하세요.

생성자

생성자는 클래스 형식의 인스턴스를 만드는 코드입니다. 클래스의 생성자는 F#에서 다른 .NET 언어와 약간 다르게 작동합니다. F# 클래스에는 항상 형식 이름 뒤에 인수가 설명 parameter-list 되고 해당 본문은 클래스 선언의 시작 부분에 있는 (및) 바인딩 및 let recdo 뒤에 있는 바인딩으로 구성 let 되는 기본 생성자가 있습니다. 기본 생성자의 인수는 클래스 선언 전체의 범위에 있습니다.

다음과 같이 키워드(keyword) 사용하여 new 멤버를 추가하여 추가 생성자를 추가할 수 있습니다.

new(argument-list) = constructor-body

새 생성자의 본문은 클래스 선언의 맨 위에 지정된 기본 생성자를 호출해야 합니다.

다음 예제에서는 이 개념을 보여 줍니다. 다음 코드 MyClass 에는 두 개의 생성자, 두 개의 인수를 사용하는 기본 생성자 및 인수를 사용하지 않는 다른 생성자가 있습니다.

type MyClass1(x: int, y: int) =
    do printfn "%d %d" x y
    new() = MyClass1(0, 0)

바인딩 허용 및 수행

let 클래스 정의의 바인딩은 do 기본 클래스 생성자의 본문을 형성하므로 클래스 인스턴스를 만들 때마다 실행됩니다. 바인딩이 let 함수인 경우 멤버로 컴파일됩니다. 바인딩이 let 함수 또는 멤버에 사용되지 않는 값인 경우 생성자에 로컬인 변수로 컴파일됩니다. 그렇지 않으면 클래스의 필드로 컴파일됩니다. 다음 식은 do 기본 생성자로 컴파일되고 모든 인스턴스에 대해 초기화 코드를 실행합니다. 모든 추가 생성자는 항상 기본 생성자를 let 호출하므로 바인딩 및 do 바인딩은 호출되는 생성자에 관계없이 항상 실행됩니다.

바인딩으로 let 만든 필드는 클래스의 메서드 및 속성 전체에서 액세스할 수 있지만 정적 메서드가 인스턴스 변수를 매개 변수로 사용하는 경우에도 정적 메서드에서 액세스할 수 없습니다. 자체 식별자가 있는 경우 자체 식별자를 사용하여 액세스할 수 없습니다.

자체 식별자

자체 식별자는 현재 인스턴스를 나타내는 이름입니다. 자체 식별자는 C# 또는 C++ Me 또는 Visual Basic의 키워드(keyword) 유사 this 합니다. 자체 식별자를 전체 클래스 정의의 범위에 둘 것인지 아니면 개별 메서드에 대한 범위에 둘 것인지에 따라 두 가지 방법으로 자체 식별자를 정의할 수 있습니다.

전체 클래스에 대한 자체 식별자를 정의하려면 생성자 매개 변수 목록의 닫는 괄호 뒤의 키워드(keyword) 사용하고 as 식별자 이름을 지정합니다.

하나의 메서드에 대한 자체 식별자를 정의하려면 메서드 이름 바로 앞에 멤버 선언에 자체 식별자를 제공하고 마침표(.)를 구분 기호로 제공합니다.

다음 코드 예제에서는 자체 식별자를 만드는 두 가지 방법을 보여 줍니다. 첫 번째 줄 as 에서 키워드(keyword) 자체 식별자를 정의하는 데 사용됩니다. 다섯 번째 줄에서 식별자는 this 범위가 메서드 PrintMessage로 제한된 자체 식별자를 정의하는 데 사용됩니다.

type MyClass2(dataIn) as self =
    let data = dataIn
    do
        self.PrintMessage()
    member this.PrintMessage() =
        printf "Creating MyClass2 with Data %d" data

다른 .NET 언어와 달리 원하는 대로 자체 식별자의 이름을 지정할 수 있습니다. 사용자는 이름(예: < Methisa0/>)으로 self제한되지 않습니다.

키워드(keyword) 선언 as 된 자체 식별자는 기본 생성자 이후까지 초기화되지 않습니다. 따라서 기본 생성자 System.InvalidOperationException: The initialization of an object or value resulted in an object or value being accessed recursively before it was fully initialized. 이전 또는 내부에서 사용되는 경우 런타임 중에 발생합니다. 바인딩 또는 do 바인딩과 같이 기본 생성자 후에 let 자유롭게 자체 식별자를 사용할 수 있습니다.

제네릭 형식 매개 변수

제네릭 형식 매개 변수는 작은따옴표와 식별자 형식으로 꺾쇠 괄호(<>)로 지정됩니다. 여러 제네릭 형식 매개 변수는 쉼표로 구분됩니다. 제네릭 형식 매개 변수는 선언 전체의 범위에 있습니다. 다음 코드 예제에서는 제네릭 형식 매개 변수를 지정하는 방법을 보여줍니다.

type MyGenericClass<'a>(x: 'a) =
    do printfn "%A" x

형식 인수는 형식을 사용할 때 유추됩니다. 다음 코드에서 유추된 형식은 튜플 시퀀스입니다.

let g1 = MyGenericClass(seq { for i in 1..10 -> (i, i * i) })

상속 지정

절이 inherit 있는 경우 직접 기본 클래스를 식별합니다. F#에서는 하나의 직접 기본 클래스만 허용됩니다. 클래스가 구현하는 인터페이스는 기본 클래스로 간주되지 않습니다. 인터페이스 항목에서는 인터페이스에 대해 설명합니다 .

언어 base 키워드(keyword) 식별자로 사용하고 마침표(.) 및 멤버 이름을 사용하여 파생 클래스에서 기본 클래스의 메서드 및 속성에 액세스할 수 있습니다.

자세한 내용은 상속을 참조하세요.

멤버 섹션

이 섹션에서는 정적 또는 인스턴스 메서드, 속성, 인터페이스 구현, 추상 멤버, 이벤트 선언 및 추가 생성자를 정의할 수 있습니다. 바인딩 허용 및 수행은 이 섹션에 표시할 수 없습니다. 멤버는 클래스 외에도 다양한 F# 형식에 추가할 수 있으므로 별도의 항목 인 멤버에서 설명합니다.

상호 재귀 형식

서로 순환 방식으로 참조하는 형식을 정의할 때는 키워드(keyword) 사용하여 형식 정의를 함께 문자열링 and 합니다. and 키워드(keyword) 다음과 같이 첫 번째 정의를 제외한 모든 키워드(keyword) 바꿉 type 니다.

open System.IO

type Folder(pathIn: string) =
    let path = pathIn
    let filenameArray: string array = Directory.GetFiles(path)
    member this.FileArray = Array.map (fun elem -> new File(elem, this)) filenameArray

and File(filename: string, containingFolder: Folder) =
    member this.Name = filename
    member this.ContainingFolder = containingFolder

let folder1 = new Folder(".")

for file in folder1.FileArray do
    printfn "%s" file.Name

출력은 현재 디렉터리에 있는 모든 파일의 목록입니다.

클래스, 공용 구조체, 레코드 및 구조를 사용하는 경우

다양한 형식 중에서 선택할 수 있는 경우 특정 상황에 적합한 형식을 선택하기 위해 각 형식이 어떤 형식으로 디자인되었는지 잘 알고 있어야 합니다. 클래스는 개체 지향 프로그래밍 컨텍스트에서 사용하도록 설계되었습니다. 개체 지향 프로그래밍은 .NET Framework용으로 작성된 애플리케이션에서 사용되는 주요 패러다임입니다. F# 코드가 .NET Framework 또는 다른 개체 지향 라이브러리와 긴밀하게 작동해야 하는 경우, 특히 UI 라이브러리와 같은 개체 지향 형식 시스템에서 확장해야 하는 경우 클래스가 적절할 수 있습니다.

개체 지향 코드와 긴밀하게 상호 운용하지 않거나 자체 포함되므로 개체 지향 코드와의 빈번한 상호 작용으로부터 보호되는 코드를 작성하는 경우 클래스, 레코드 및 구분된 공용 구조체를 혼합하여 사용하는 것이 좋습니다. 적절한 패턴 일치 코드와 함께 잘 알려진 단일 구분 공용 구조체를 개체 계층 구조에 대한 간단한 대안으로 사용할 수 있습니다. 차별된 노조에 대한 자세한 내용은 차별된 노조를 참조 하세요.

레코드는 클래스보다 단순하다는 장점이 있지만 형식의 요구가 단순성으로 수행할 수 있는 것을 초과하는 경우 레코드는 적절하지 않습니다. 레코드는 기본적으로 값의 간단한 집계이며, 사용자 지정 작업을 수행할 수 있는 별도의 생성자가 없고, 숨겨진 필드가 없고, 상속 또는 인터페이스 구현이 없습니다. 속성 및 메서드와 같은 멤버를 레코드에 추가하여 동작을 더 복잡하게 만들 수 있지만 레코드에 저장된 필드는 여전히 값의 간단한 집계입니다. 레코드에 대한 자세한 내용은 레코드를 참조하세요.

구조체는 작은 데이터 집계에도 유용하지만 클래스 및 레코드는 .NET 값 형식이라는 점에서 다릅니다. 클래스 및 레코드는 .NET 참조 형식입니다. 값 형식과 참조 형식의 의미 체계는 값 형식이 값으로 전달된다는 측면에서 다릅니다. 즉, 매개 변수로 전달되거나 함수에서 반환될 때 비트에 대해 비트가 복사됩니다. 또한 스택에 저장되거나 필드로 사용되는 경우 힙의 별도의 위치에 저장되지 않고 부모 개체 내에 포함됩니다. 따라서 구조는 힙 액세스 오버헤드가 문제가 될 때 자주 액세스하는 데이터에 적합합니다. 구조체에 대한 자세한 내용은 구조체를 참조 하세요.

참고 항목