Dela via


Arv

Arv används för att modellera "is-a"-relationen, eller undertypning, i objektorienterad programmering.

Ange arvsrelationer

Du anger arvsrelationer med hjälp av nyckelordet inherit i en klassdeklaration. Det grundläggande syntaktiska formuläret visas i följande exempel.

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

En klass kan ha högst en direkt basklass. Om du inte anger en basklass med hjälp av nyckelordet inherit ärver klassen implicit från System.Object.

Ärvda medlemmar

Om en klass ärver från en annan klass är metoderna och medlemmarna i basklassen tillgängliga för användare av den härledda klassen som om de vore direkta medlemmar i den härledda klassen.

Alla let-bindningar och konstruktorparametrar är privata för en klass och kan därför inte nås från härledda klasser.

Nyckelordet base är tillgängligt i härledda klasser och refererar till basklassinstansen. Den används som självidentifierare.

Virtuella metoder och åsidosättningar

Virtuella metoder (och egenskaper) fungerar något annorlunda i F# jämfört med andra .NET-språk. Om du vill deklarera en ny virtuell medlem använder du nyckelordet abstract . Det gör du oavsett om du anger en standardimplementering för den metoden. En fullständig definition av en virtuell metod i en basklass följer därför det här mönstret:

abstract member [method-name] : [type]

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

Och i en härledd klass följer en åsidosättning av den här virtuella metoden det här mönstret:

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

Om du utelämnar standardimplementeringen i basklassen blir basklassen en abstrakt klass.

Följande kodexempel illustrerar deklarationen av en ny virtuell metod function1 i en basklass och hur du åsidosätter den i en härledd klass.

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

Konstruktorer och arv

Konstruktorn för basklassen måste anropas i den härledda klassen. Argumenten för basklasskonstruktorn visas i argumentlistan i inherit -satsen. De värden som används måste bestämmas utifrån argumenten som skickas till den härledda klasskonstruktorn.

Följande kod visar en basklass och en härledd klass, där den härledda klassen anropar basklasskonstruktorn i ärv-satsen:

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

När det gäller flera konstruktorer kan följande kod användas. Den första raden i de härledda klasskonstruktorerna är inherit -satsen och fälten visas som explicita fält som deklareras med nyckelordet val . Mer information finns i Explicita fält: Nyckelordetval.

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")

Alternativ till arv

Om en mindre ändring av en typ krävs bör du överväga att använda ett objektuttryck som ett alternativ till arv. I följande exempel visas användningen av ett objektuttryck som ett alternativ till att skapa en ny härledd typ:

open System

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

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

Mer information om objektuttryck finns i Objektuttryck.

När du skapar objekthierarkier bör du överväga att använda en diskriminerad union i stället för arv. Diskriminerade fackföreningar kan också modellera olika beteenden för olika objekt som delar en gemensam övergripande typ. En enda diskriminerad union kan ofta eliminera behovet av ett antal härledda klasser som är mindre variationer av varandra. Information om diskriminerade fackföreningar finns i Diskriminerade fackföreningar.

Se även