다음을 통해 공유


상속

상속은 개체 지향 프로그래밍에서 "is-a" 관계 또는 하위 스타일을 모델링하는 데 사용됩니다.

상속 관계 지정

클래스 선언에서 inherit 키워드(keyword) 사용하여 상속 관계를 지정합니다. 기본 구문 형식은 다음 예제에 나와 있습니다.

type MyDerived(...) =
    inherit MyBase(...)

클래스에는 최대 하나의 직접 기본 클래스가 있을 수 있습니다. 키워드(keyword) 사용하여 기본 클래스를 inherit 지정하지 않으면 클래스는 암시적으로 상속됩니다System.Object.

상속된 멤버

클래스가 다른 클래스에서 상속되는 경우 파생 클래스의 사용자가 파생 클래스의 직접 멤버인 것처럼 기본 클래스의 메서드와 멤버를 사용할 수 있습니다.

let 바인딩 및 생성자 매개 변수는 클래스에 대한 프라이빗이므로 파생 클래스에서 액세스할 수 없습니다.

키워드(keyword) base 파생 클래스에서 사용할 수 있으며 기본 클래스 인스턴스를 참조합니다. 자체 식별자처럼 사용됩니다.

가상 메서드 및 재정의

가상 메서드(및 속성)는 다른 .NET 언어에 비해 F#에서 다소 다르게 작동합니다. 새 가상 멤버를 선언하려면 키워드(keyword) 사용합니다 abstract . 이 작업은 해당 메서드에 대한 기본 구현을 제공하는지 여부에 관계없이 수행합니다. 따라서 기본 클래스의 가상 메서드에 대한 전체 정의는 다음 패턴을 따릅니다.

abstract member [method-name] : [type]

default [self-identifier].[method-name] [argument-list] = [method-body]

파생 클래스에서 이 가상 메서드의 재정의는 다음 패턴을 따릅니다.

override [self-identifier].[method-name] [argument-list] = [method-body]

기본 클래스에서 기본 구현을 생략하면 기본 클래스가 추상 클래스가 됩니다.

다음 코드 예제에서는 기본 클래스에서 새 가상 메서드 function1 의 선언 및 파생된 클래스에서 재정의 하는 방법을 보여 줍니다.

type MyClassBase1() =
    let mutable z = 0
    abstract member function1: int -> int

    default u.function1(a: int) =
        z <- z + a
        z

type MyClassDerived1() =
    inherit MyClassBase1()
    override u.function1(a: int) = a + 1

생성자 및 상속

파생 클래스에서 기본 클래스에 대한 생성자를 호출해야 합니다. 기본 클래스 생성자에 대한 인수는 절의 인수 목록에 inherit 나타납니다. 사용되는 값은 파생 클래스 생성자에 제공된 인수에서 결정되어야 합니다.

다음 코드는 파생 클래스가 상속 절에서 기본 클래스 생성자를 호출하는 기본 클래스 및 파생 클래스를 보여줍니다.

type MyClassBase2(x: int) =
    let mutable z = x * x

    do
        for i in 1..z do
            printf "%d " i


type MyClassDerived2(y: int) =
    inherit MyClassBase2(y * 2)

    do
        for i in 1..y do
            printf "%d " i

여러 생성자의 경우 다음 코드를 사용할 수 있습니다. 파생 클래스 생성자의 첫 번째 줄은 절이며 inherit 필드는 키워드(keyword) 선언된 val 명시적 필드로 나타납니다. 자세한 내용은 명시적 필드: 키 val 워드를 참조하세요.

type BaseClass =
    val string1 : string
    new (str) = { string1 = str }
    new () = { string1 = "" }

type DerivedClass =
    inherit BaseClass

    val string2 : string
    new (str1, str2) = { inherit BaseClass(str1); string2 = str2 }
    new (str2) = { inherit BaseClass(); string2 = str2 }

let obj1 = DerivedClass("A", "B")
let obj2 = DerivedClass("A")

상속에 대한 대안

형식을 약간 수정해야 하는 경우 상속 대신 개체 식을 사용하는 것이 좋습니다. 다음 예제에서는 새 파생 형식을 만드는 대신 개체 식을 사용하는 방법을 보여 줍니다.

open System

let object1 =
    { new Object() with
        override this.ToString() = "This overrides object.ToString()" }

printfn "%s" (object1.ToString())

개체 식에 대한 자세한 내용은 개체 식을 참조 하세요.

개체 계층을 만들 때 상속 대신 구분된 공용 구조체를 사용하는 것이 좋습니다. 구분된 공용 구조체는 일반적인 전체 형식을 공유하는 다양한 개체의 다양한 동작을 모델링할 수도 있습니다. 차별된 단일 공용 구조체는 종종 서로의 사소한 변형인 여러 파생 클래스의 필요성을 제거할 수 있습니다. 차별된 노조에 대한 자세한 내용은 차별된 노조를 참조 하세요.

참고 항목