Soyut Sınıflar

Soyut sınıflar , uygulamaların türetilmiş sınıflar tarafından sağlanabilmesi için üyelerin bir kısmını veya tümünü engellenmemiş olarak bırakan sınıflardır.

Sözdizimi

// 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

Açıklamalar

Nesne odaklı programlamada soyut sınıf, bir hiyerarşinin temel sınıfı olarak kullanılır ve çeşitli nesne türleri kümesinin ortak işlevselliğini temsil eder. "Soyut" adından da anlaşılacağı gibi, soyut sınıflar genellikle sorun etki alanındaki somut varlıklara doğrudan karşılık gelmez. Ancak, birçok farklı somut varlığın ortak olanlarını temsil eder.

Soyut sınıflar özniteliğine AbstractClass sahip olmalıdır. Bu kişiler, üyeleri uygulamış ve tanımlanamayan üyelere sahip olabilir. Bir sınıfa uygulandığında soyut teriminin kullanılması diğer .NET dillerindekiyle aynıdır; ancak F# dilinde soyut teriminin yöntemlere (ve özelliklere) uygulandığında kullanılması, F# dilindeki diğer .NET dillerindeki kullanımından biraz farklıdır. F# dilinde, bir yöntem anahtar sözcüğüyle abstract işaretlendiğinde, bu, üyenin bu tür için iç sanal işlevler tablosunda sanal dağıtım yuvası olarak bilinen bir girdisi olduğunu gösterir. Başka bir deyişle, anahtar sözcüğü F# dilinde kullanılmasa da virtual yöntemi sanaldır. anahtar sözcüğü abstract , yöntemin uygulanıp uygulanmadığına bakılmaksızın sanal yöntemler üzerinde kullanılır. Sanal dağıtım yuvası bildirimi, bu dağıtım yuvası için bir yöntemin tanımından ayrıdır. Bu nedenle, başka bir .NET dilindeki bir sanal yöntem bildirimi ve tanımının F# eşdeğeri, hem soyut yöntem bildiriminin hem de anahtar sözcüğün veya anahtar sözcüğün default ayrı bir tanımının override birleşimidir. Daha fazla bilgi ve örnek için bkz . Yöntemler.

Bir sınıf yalnızca bildirilen ancak tanımlanmayan soyut yöntemler varsa soyut olarak kabul edilir. Bu nedenle, soyut yöntemleri olan sınıflar mutlaka soyut sınıflar değildir. Bir sınıfın tanımlanmamış soyut yöntemleri olmadığı sürece AbstractClass özniteliğini kullanmayın.

Önceki söz diziminde erişilebilirlik değiştiricisi veya privateinternalolabilirpublic. Daha fazla bilgi için bkz. Erişim Denetimi.

Diğer türlerde olduğu gibi soyut sınıfların da bir temel sınıfı ve bir veya daha fazla temel arabirimi olabilir. Her temel sınıf veya arabirim, anahtar sözcüğüyle birlikte ayrı bir satırda inherit görünür.

Soyut sınıfın tür tanımı tam tanımlı üyeler içerebilir, ancak soyut üyeler de içerebilir. Soyut üyelerin söz dizimi önceki söz diziminde ayrı olarak gösterilir. Bu söz diziminde, bir üyenin tür imzası, sıralı parametre türlerini ve döndürülen türleri içeren bir listedir ve kümelenmiş ve kümelenmiş parametreler için uygun belirteçler ve/veya * belirteçlerle ayrılmıştır->. Soyut üye türü imzalarının söz dizimi, imza dosyalarında kullanılan ve Visual Studio Code Düzenleyicisi'nde IntelliSense tarafından gösterilen söz dizimi ile aynıdır.

Aşağıdaki kod, soyut olmayan türetilmiş iki sınıfa (Square ve Circle) sahip olan bir soyut sınıf Shape'ı gösterir. Örnekte soyut sınıfların, yöntemlerin ve özelliklerin nasıl kullanılacağı gösterilmektedir. Örnekte, shape soyut sınıfı, beton varlıkların daire ve kare ortak öğelerini temsil eder. Tüm şekillerin ortak özellikleri (iki boyutlu koordinat sisteminde) Shape sınıfına soyutlanır: kılavuzdaki konum, döndürme açısı ve alan ve çevre özellikleri. Konum dışında, tek tek şekillerin değiştiremediği davranışlar geçersiz kılınabilir.

Döndürme yöntemi, simetrisi nedeniyle dönme sabiti olan Circle sınıfında olduğu gibi geçersiz kılınabilir. Bu nedenle Circle sınıfında döndürme yöntemi hiçbir şey içermeyen bir yöntemle değiştirilir.

// 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
    // overridden.
    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

Çıkış:

Perimeter of square with side length 10.000000 is 40.000000
Circumference of circle with radius 5.000000 is 31.415927
Area of Square: 100.000000
Area of Circle: 78.539816

Ayrıca bkz.