Konstruktorok
Ez a cikk azt ismerteti, hogyan definiálhat és használhat konstruktorokat osztály- és struktúraobjektumok létrehozására és inicializálására.
Osztályobjektumok felépítése
Az osztálytípusok objektumai konstruktorokkal rendelkeznek. Kétféle konstruktor létezik. Az egyik az elsődleges konstruktor, amelynek paraméterei zárójelben jelennek meg a típus neve után. A kulcsszó használatával new
további, opcionális konstruktorokat is megadhat. Minden ilyen további konstruktornak meg kell hívnia az elsődleges konstruktort.
Az elsődleges konstruktor az osztálydefiníció elején megjelenő kötéseket tartalmazza és do
kötilet
. A let
kötés az osztály privát mezőit és metódusait deklarálja, a do
kötés pedig kódot hajt végre. További információ az osztálykonstruktorok kötéseiről let
: let
Kötések az osztályokban. A konstruktorok kötéseiről további információt do
az osztályok kötései című témakörben találdo
.
Függetlenül attól, hogy a meghívni kívánt konstruktor elsődleges konstruktor vagy további konstruktor, létrehozhat objektumokat egy new
kifejezéssel, az opcionális new
kulcsszóval vagy anélkül. Az objektumokat konstruktorargumentumokkal együtt inicializálhatja az argumentumok sorrendbe sorolásával, vesszővel elválasztva és zárójelben elválasztva, vagy elnevezett argumentumok és értékek zárójelben való használatával. Az objektumon a tulajdonságokat a tulajdonságnevek használatával és az értékek hozzárendelésével is beállíthatja az objektumon, ahogyan a nevesített konstruktorargumentumokat használja.
Az alábbi kód egy konstruktort tartalmazó osztályt és az objektumok létrehozásának különböző módjait mutatja be:
// This class has a primary constructor that takes three arguments
// and an additional constructor that calls the primary constructor.
type MyClass(x0, y0, z0) =
let mutable x = x0
let mutable y = y0
let mutable z = z0
do
printfn "Initialized object that has coordinates (%d, %d, %d)" x y z
member this.X with get() = x and set(value) = x <- value
member this.Y with get() = y and set(value) = y <- value
member this.Z with get() = z and set(value) = z <- value
new() = MyClass(0, 0, 0)
// Create by using the new keyword.
let myObject1 = new MyClass(1, 2, 3)
// Create without using the new keyword.
let myObject2 = MyClass(4, 5, 6)
// Create by using named arguments.
let myObject3 = MyClass(x0 = 7, y0 = 8, z0 = 9)
// Create by using the additional constructor.
let myObject4 = MyClass()
A kimenet a következő:
Initialized object that has coordinates (1, 2, 3)
Initialized object that has coordinates (4, 5, 6)
Initialized object that has coordinates (7, 8, 9)
Initialized object that has coordinates (0, 0, 0)
Szerkezetek felépítése
A struktúrák az osztályok minden szabályát követik. Ezért rendelkezhet elsődleges konstruktorsal, és további konstruktorokat is megadhat a használatával new
. A struktúrák és osztályok között azonban van egy fontos különbség: a struktúrák paraméter nélküli konstruktorsal (vagyis argumentumok nélkül) rendelkezhetnek akkor is, ha nincs meghatározva elsődleges konstruktor. A paraméter nélküli konstruktor inicializálja az összes mezőt az adott típus alapértelmezett értékére, általában nulla vagy azzal egyenértékű értékre. A struktúrákhoz definiált konstruktoroknak legalább egy argumentummal kell rendelkezniük, hogy ne ütközhessenek a paraméter nélküli konstruktorral.
A struktúrákban gyakran vannak olyan mezők is, amelyek a val
kulcsszó használatával jönnek létre; az osztályok is tartalmazhatnak ilyen mezőket. A kulcsszóval val
definiált mezőkkel rendelkező struktúrák és osztályok további konstruktorokban is inicializálhatók rekordkifejezések használatával, ahogyan az az alábbi kódban is látható.
type MyStruct =
struct
val X : int
val Y : int
val Z : int
new(x, y, z) = { X = x; Y = y; Z = z }
end
let myStructure1 = new MyStruct(1, 2, 3)
További információ: Explicit mezők: A val
kulcsszó.
Mellékhatások végrehajtása konstruktorokban
Az osztály elsődleges konstruktorai kódot hajthatnak végre egy do
kötésben. Mi a teendő azonban, ha egy további konstruktorban, kötés nélkül kell végrehajtania a do
kódot? Ehhez a kulcsszót then
kell használnia.
// Executing side effects in the primary constructor and
// additional constructors.
type Person(nameIn : string, idIn : int) =
let mutable name = nameIn
let mutable id = idIn
do printfn "Created a person object."
member this.Name with get() = name and set(v) = name <- v
member this.ID with get() = id and set(v) = id <- v
new() =
Person("Invalid Name", -1)
then
printfn "Created an invalid person object."
let person1 = new Person("Humberto Acevedo", 123458734)
let person2 = new Person()
Az elsődleges konstruktor mellékhatásai még mindig végrehajtásra várnak. Ezért a kimenet a következő:
Created a person object.
Created a person object.
Created an invalid person object.
then
A másik do
helyett azért van szükség rá, mert a do
kulcsszó szabványos jelentése egy unit
-returning kifejezés elválasztása, ha egy további konstruktor törzsében jelen van. Csak az elsődleges konstruktorok kontextusában különleges jelentéssel rendelkezik.
Önazonosítók konstruktorokban
A többi tagban az egyes tagok definíciójában adja meg az aktuális objektum nevét. Az önazonosítót az osztálydefiníció első sorára is elhelyezheti a as
konstruktorparamétereket közvetlenül követő kulcsszó használatával. Az alábbi példa ezt a szintaxist szemlélteti.
type MyClass1(x) as this =
// This use of the self identifier produces a warning - avoid.
let x1 = this.X
// This use of the self identifier is acceptable.
do printfn "Initializing object with X =%d" this.X
member this.X = x
További konstruktorokban önazonosítót is definiálhat, ha közvetlenül a as
konstruktorparaméterek után helyezi el a záradékot. Az alábbi példa ezt a szintaxist szemlélteti:
type MyClass2(x : int) =
member this.X = x
new() as this = MyClass2(0) then printfn "Initializing with X = %d" this.X
Problémák léphetnek fel, ha egy objektumot a teljes definiálás előtt próbál használni. Ezért az önazonosító használata miatt a fordító figyelmeztetést ad ki, és további ellenőrzéseket szúr be annak érdekében, hogy az objektum tagjai ne férjenek hozzá az objektum inicializálása előtt. Az önazonosítót csak az do
elsődleges konstruktor kötéseiben vagy a then
további konstruktorok kulcsszója után szabad használni.
Az önazonosító nevének nem kell lennie this
. Bármilyen érvényes azonosító lehet.
Értékek hozzárendelése tulajdonságokhoz inicializáláskor
Az inicializálási kódban egy osztályobjektum tulajdonságaihoz rendelhet értékeket úgy, hogy hozzáfűzi az űrlap property = value
hozzárendeléseinek listáját egy konstruktor argumentumlistájához. Ez a következő kód példában látható:
type Account() =
let mutable balance = 0.0
let mutable number = 0
let mutable firstName = ""
let mutable lastName = ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
let account1 = new Account(AccountNumber=8782108,
FirstName="Darren", LastName="Parker",
Balance=1543.33)
Az előző kód alábbi verziója a szokásos argumentumok, választható argumentumok és tulajdonságbeállítások kombinációját mutatja be egy konstruktorhívásban:
type Account(accountNumber : int, ?first: string, ?last: string, ?bal : float) =
let mutable balance = defaultArg bal 0.0
let mutable number = accountNumber
let mutable firstName = defaultArg first ""
let mutable lastName = defaultArg last ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
let account1 = new Account(8782108, bal = 543.33,
FirstName="Raman", LastName="Iyer")
Konstruktorok az örökölt osztályban
Ha konstruktort tartalmazó alaposztályból örököl, az öröklési záradékban meg kell adnia az argumentumait. További információ: Konstruktorok és öröklés.
Statikus konstruktorok vagy típuskonstruktorok
Az objektumok létrehozásához szükséges kód megadása mellett a statikus let
és do
kötések olyan osztálytípusokban is létrehozhatók, amelyek a típus első használata előtt végrehajtják az inicializálást a típus szintjén. További információ: let
Kötések osztályokban és do
kötések az osztályokban.
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: