Delen via


Overname

Overname wordt gebruikt om de 'is-a'-relatie, of subtyping, te modelleren in objectgeoriënteerde programmering.

Overnamerelaties opgeven

U geeft overnamerelaties op met behulp van het inherit trefwoord in een klassedeclaratie. Het syntacticale basisformulier wordt weergegeven in het volgende voorbeeld.

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

Een klasse kan maximaal één directe basisklasse hebben. Als u geen basisklasse opgeeft met behulp van het inherit trefwoord, neemt de klasse impliciet over van System.Object.

Overgenomen leden

Als een klasse overdrat van een andere klasse, zijn de methoden en leden van de basisklasse beschikbaar voor gebruikers van de afgeleide klasse alsof ze directe leden van de afgeleide klasse zijn.

Bindingen en constructorparameters zijn privé voor een klasse en kunnen daarom niet worden geopend vanuit afgeleide klassen.

Het trefwoord base is beschikbaar in afgeleide klassen en verwijst naar het exemplaar van de basisklasse. Het wordt gebruikt als de self-id.

Virtuele methoden en onderdrukkingen

Virtuele methoden (en eigenschappen) werken enigszins anders in F# in vergelijking met andere .NET-talen. Als u een nieuw virtueel lid wilt declareren, gebruikt u het abstract trefwoord. U doet dit ongeacht of u een standaard implementatie voor die methode opgeeft. Een volledige definitie van een virtuele methode in een basisklasse volgt dus dit patroon:

abstract member [method-name] : [type]

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

En in een afgeleide klasse volgt een onderdrukking van deze virtuele methode dit patroon:

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

Als u de standaard implementatie in de basisklasse weglaat, wordt de basisklasse een abstracte klasse.

In het volgende codevoorbeeld ziet u de declaratie van een nieuwe virtuele methode function1 in een basisklasse en hoe u deze kunt overschrijven in een afgeleide klasse.

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

Constructors en overname

De constructor voor de basisklasse moet worden aangeroepen in de afgeleide klasse. De argumenten voor de basisklasseconstructor worden weergegeven in de argumentenlijst in de inherit component. De waarden die worden gebruikt, moeten worden bepaald op basis van de argumenten die zijn opgegeven aan de afgeleide klasseconstructor.

De volgende code toont een basisklasse en een afgeleide klasse, waarbij de afgeleide klasse de basisklasseconstructor aanroept in de overnamecomponent:

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

In het geval van meerdere constructors kan de volgende code worden gebruikt. De eerste regel van de afgeleide klasseconstructors is de inherit component en de velden worden weergegeven als expliciete velden die met het val trefwoord worden gedeclareerd. Zie Expliciete velden: Het val trefwoord voor meer informatie.

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

Alternatieven voor overname

In gevallen waarin een kleine wijziging van een type vereist is, kunt u overwegen een objectexpressie te gebruiken als alternatief voor overname. In het volgende voorbeeld ziet u het gebruik van een objectexpressie als alternatief voor het maken van een nieuw afgeleid type:

open System

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

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

Zie Objectexpressies voor meer informatie over objectexpressies.

Wanneer u objecthiërarchieën maakt, kunt u overwegen een gediscrimineerde samenvoeging te gebruiken in plaats van overname. Gediscrimineerde vakbonden kunnen ook gevarieerd gedrag modelleren van verschillende objecten die een gemeenschappelijk algemeen type delen. Een enkele gediscrimineerde samenvoeging kan vaak voorkomen dat een aantal afgeleide klassen kleine variaties van elkaar zijn. Zie Gediscrimineerde vakbonden voor informatie over gediscrimineerde vakbonden.

Zie ook