Udostępnij za pośrednictwem


Klasy abstrakcyjne (F#)

Klasy abstrakcyjne są klasy, które opuszczają niektórych lub wszystkich członków niezaimplementowane, tak aby implementacji może być udostępniane przez klas pochodnych.

// Abstract class syntax.
[<AbstractClass>]
type [ accessibility-modifier ] abstract-class-name =
    [ inherit base-class-or-interface-name ]
    [ abstract-member-declarations-and-member-definitions ]

// Abstract member syntax.
    abstract member member-name : type-signature

Uwagi

W programowaniu zorientowanym obiektowo, klasa abstrakcyjna służy jako klasa podstawowa hierarchii i stanowi często używane funkcje zestaw typów obiektów.Jak sugeruje nazwa "abstract", klasy abstrakcyjne często nie odpowiadają bezpośrednio na konkretne podmioty w domenie problem.Jednak stanowią one co wielu różnych podmiotów konkretnych mają wspólne.

Abstrakcyjne klasy musi mieć AbstractClass atrybut.Można mieć zaimplementowany i niezaimplementowane członków.Użycie terminu abstrakcyjna po zastosowaniu do klasy jest taka sama, jak w innych.Języki netto; Jednak użycie terminu abstrakcyjna po zastosowaniu metod (i właściwości) jest nieco inny w F# z jego stosowania w innych.Języki netto.F#, gdy metoda jest oznaczona z abstract słowa kluczowego, to wskazuje, że członek ma wpis, znany jako wirtualnych wysyłki gniazdo, w wewnętrznej tabeli wirtualnej funkcji dla tego typu.Innymi słowy, metoda jest wirtualna, chociaż virtual słowo kluczowe nie jest używana w języku F#.Słowo kluczowe abstract jest używana w metodach wirtualnych, niezależnie od tego, czy metoda została zaimplementowana.Deklarację gniazdo wirtualnego wysyłki jest niezależna od definicji metody dla tego gniazda wysyłki.W związku z tym F# równoważna metoda wirtualna deklaracji i definicji w innym.Język netto jest kombinacją zarówno deklarację metoda abstrakcyjna i odrębnej definicji, z albo default słowa kluczowego lub override słowa kluczowego.Aby uzyskać dodatkowe informacje i przykłady, zobacz Metody (F#).

Klasa jest uważany za abstrakcyjne tylko wtedy, gdy istnieją metody abstrakcyjne zadeklarowana, ale nie jest zdefiniowany.W związku z tym klasami, które zawierają metody abstrakcyjne nie są koniecznie abstrakcyjne klasy.Nie należy używać, chyba że klasa zawiera niezdefiniowane metody abstrakcyjne, AbstractClass atrybut.

In the previous syntax, accessibility-modifier can be public, private or internal.Aby uzyskać więcej informacji, zobacz Kontrola dostępu (F#).

Podobnie jak w przypadku innych typów klasy abstrakcyjne może mieć klasy podstawowej i jednym lub kilkoma oprzeć interfejsów.Każda klasa podstawowa lub interfejsu pojawia się w osobnym wierszu, wraz z inherit słowa kluczowego.

Definicja typu klasy abstrakcyjnej mogą zawierać członków zdefiniowanych w pełni, ale może również zawierać członków abstrakcyjny.Składni abstrakcyjnej członków oddzielnie pokazano składnię poprzedniego.W tej składni type signature członka jest lista, która zawiera parametr typy w kolejności i zwracanych typów oddzielone -> tokenów i/lub * tokeny odpowiednio dla curried i tupled parametry.Składnia abstrakcyjnego członka typu podpisów jest taka sama, jak używane w plikach podpisu oraz wykazane, przez technologię IntelliSense w edytorze kodu Visual Studio.

Przykład

Poniższy kod ilustruje klasa abstrakcyjna Shape, który ma dwie klasy pochodnej nieabstrakcyjna, Square i Circle.W przykładzie przedstawiono sposób korzystania z klasy abstrakcyjne, metod i właściwości.Na przykład klasa abstrakcyjna Shape reprezentuje wspólne elementy konkretne podmioty circle i square.Wspólne cechy wszystkich kształtów (w dwuwymiarowym układzie współrzędnych) są wydobywane out do Shape klasy: pozycji na siatce, kąt obrotu i właściwości powierzchni i obwodu.Te może zostać zastąpiona, z wyjątkiem pozycji, zachowanie, którego nie można zmienić poszczególne kształty.

Metoda obrót może zostać zastąpiona, jak w Circle klasy, która jest niezmienny rotacji z powodu jego symetrii.Tak w Circle klasy, metody obracania zastępuje metodę, że nic nie robi.

// An abstract class that has some methods and properties defined 
// and some left abstract.
[<AbstractClass>]
type Shape2D(x0 : float, y0 : float) =
    let mutable x, y = x0, y0
    let mutable rotAngle = 0.0

    // These properties are not declared abstract. They 
    // cannot be overriden. 
    member this.CenterX with get() = x and set xval = x <- xval
    member this.CenterY with get() = y and set yval = y <- yval

    // These properties are abstract, and no default implementation 
    // is provided. Non-abstract derived classes must implement these. 
    abstract Area : float with get
    abstract Perimeter : float  with get
    abstract Name : string with get

    // This method is not declared abstract. It cannot be 
    // overriden. 
    member this.Move dx dy =
       x <- x + dx
       y <- y + dy

    // An abstract method that is given a default implementation 
    // is equivalent to a virtual method in other .NET languages. 
    // Rotate changes the internal angle of rotation of the square. 
    // Angle is assumed to be in degrees. 
    abstract member Rotate: float -> unit
    default this.Rotate(angle) = rotAngle <- rotAngle + angle

type Square(x, y, sideLengthIn) =
    inherit Shape2D(x, y)
    member this.SideLength = sideLengthIn
    override this.Area = this.SideLength * this.SideLength
    override this.Perimeter = this.SideLength * 4.
    override this.Name = "Square" 

type Circle(x, y, radius) =
    inherit Shape2D(x, y)
    let PI = 3.141592654
    member this.Radius = radius
    override this.Area = PI * this.Radius * this.Radius
    override this.Perimeter = 2. * PI * this.Radius
    // Rotating a circle does nothing, so use the wildcard 
    // character to discard the unused argument and  
    // evaluate to unit. 
    override this.Rotate(_) = ()
    override this.Name = "Circle" 

let square1 = new Square(0.0, 0.0, 10.0)
let circle1 = new Circle(0.0, 0.0, 5.0)
circle1.CenterX <- 1.0
circle1.CenterY <- -2.0
square1.Move -1.0 2.0
square1.Rotate 45.0
circle1.Rotate 45.0
printfn "Perimeter of square with side length %f is %f, %f"
        (square1.SideLength) (square1.Area) (square1.Perimeter)
printfn "Circumference of circle with radius %f is %f, %f"
        (circle1.Radius) (circle1.Area) (circle1.Perimeter)

let shapeList : list<Shape2D> = [ (square1 :> Shape2D);
                                  (circle1 :> Shape2D) ]
List.iter (fun (elem : Shape2D) ->
              printfn "Area of %s: %f" (elem.Name) (elem.Area))
          shapeList
  

Zobacz też

Informacje

Klasy (F#)

Metody (F#)

Właściwości (F#)

Inne zasoby

Członkowie (F#)