Klassen
F# unterstützt die Objektorientierung vollständig:
type Tier(name: string) =
member _.Name = name
abstract Laut: unit -> string
default _.Laut() = "..."
member this.Vorstellen() = sprintf "%s sagt %s" name (this.Laut())
type Hund(name: string) =
inherit Tier(name)
override _.Laut() = "Wau"
type Katze(name: string) =
inherit Tier(name)
override _.Laut() = "Miau"
let tiere: Tier list = [ Hund "Rex"; Katze "Mimi"; Tier "Fisch" ]
for t in tiere do printfn "%s" (t.Vorstellen())
type Zaehler() =
let mutable n = 0
member _.Erhoehe() = n <- n + 1
member _.Wert = n
let z = Zaehler()
z.Erhoehe()
z.Erhoehe()
printfn "%d" z.Wert
printfn "%b" (tiere.[0] :? Hund)Ausgabe
Rex sagt Wau Mimi sagt Miau Fisch sagt ... 2 true
Interfaces und Objektausdrücke
type IGruss =
abstract Sage: string -> string
type Deutsch() =
interface IGruss with
member _.Sage(name) = "Guten Tag, " + name
let g: IGruss = Deutsch()
printfn "%s" (g.Sage "Mia")
let englisch =
{ new IGruss with
member _.Sage(name) = "Hello, " + name }
printfn "%s" (englisch.Sage "Tom")
type Vektor =
{ X: float; Y: float }
static member (+)(a, b) = { X = a.X + b.X; Y = a.Y + b.Y }
static member (*)(v, s) = { X = v.X * s; Y = v.Y * s }
let v = { X = 1.0; Y = 2.0 } + { X = 3.0; Y = 4.0 }
printfn "%A" (v * 2.0)
type System.String with
member s.Wiederhole(n) = String.replicate n s
printfn "%s" ("ab".Wiederhole 3)Ausgabe
Guten Tag, Mia
Hello, Tom
{ X = 8.0
Y = 12.0 }
abababModule
Module gruppieren Funktionen und Werte; Namensräume gruppieren Module und Typen:
module Geometrie =
let pi = 3.14159
let kreisflaeche r = pi * r * r
let rechteckflaeche b h = b * h
module Intern =
let hilfe x = x * 2.0
module Text =
let wiederhole n (s: string) = String.replicate n s
let istPalindrom (s: string) =
let t = s.ToLower() |> Seq.filter System.Char.IsLetter |> Seq.toList
t = List.rev t
printfn "%.2f" (Geometrie.kreisflaeche 1.0)
printfn "%.1f" (Geometrie.Intern.hilfe 4.0)
printfn "%s" (Text.wiederhole 3 "ab")
printfn "%b %b" (Text.istPalindrom "Anna") (Text.istPalindrom "F#")
open Geometrie
printfn "%.1f" (rechteckflaeche 3.0 4.0)Ausgabe
3.14 8.0 ababab true true 12.0
Generics und Constraints
type Stapel<'T> = { Daten: 'T list }
module Stapel =
let leer = { Daten = [] }
let push x s = { Daten = x :: s.Daten }
let pop s =
match s.Daten with
| [] -> None
| x :: rest -> Some(x, { Daten = rest })
let s = Stapel.leer |> Stapel.push 1 |> Stapel.push 2 |> Stapel.push 3
match Stapel.pop s with
| Some(oben, _) -> printfn "oben: %d" oben
| None -> printfn "leer"
let groesster<'a when 'a: comparison> (liste: 'a list) = List.max liste
let kleinster<'a when 'a: comparison> (liste: 'a list) = List.min liste
printfn "%d %s" (groesster [ 3; 9; 4 ]) (kleinster [ "b"; "z"; "a" ])
let inline quadrat x = x * x
printfn "%d %.2f" (quadrat 7) (quadrat 1.5)Ausgabe
oben: 3 9 a 49 2.25
Merke
- Klassen: Primärkonstruktor,
member,abstract/default/override,inherit - Interfaces mit
interface ... with, Objektausdrücke{ new ... } - Module (
module) gruppieren Code; Operatoren lassen sich auf Typen überladen - Generics (
'T) mit Constraints (when 'a: comparison) undinline
Aufgabe
Modelliere Konto als Klasse mit Einzahlen, Abheben und einem Interface IKonto.