Classes abstratas (F#)

Resumo de classes são classes que deixar alguns ou todos os membros que não implementados, para que as implementações podem ser fornecidas pelas classes derivadas.

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

Comentários

Na programação orientada a objeto, uma classe abstrata é usada como uma classe base de uma hierarquia e representa a funcionalidade comum de um conjunto diversificado de tipos de objeto. Como o nome "abstrato" implica classes abstratas geralmente não correspondem diretamente em entidades concretas do domínio do problema. No entanto, eles representam o que muitos diferentes entidades concretas que têm em comum.

Classes abstratas devem ter o AbstractClass atributo. Ter implementado e não implementado membros. O uso do termo abstrata quando aplicado a uma classe é o mesmo do outro.NET idiomas; No entanto, o uso do termo abstrata quando aplicado a métodos (e propriedades) é um pouco diferente no F# de seu uso em outros.NET idiomas. Em F#, quando um método está marcado com o abstract palavra-chave, isso indica que o membro tem uma entrada, conhecida como um slot de despacho virtual, na tabela interna de funções virtuais para esse tipo. Em outras palavras, o método é virtual, embora o virtual palavra-chave não é usado no F# do idioma. A palavra-chave abstract é usado em métodos virtuais independentemente, por exemplo, se o método é implementado. A declaração de um slot de despacho virtual é separada da definição de um método para esse slot de despacho. Portanto, o F# equivalente de uma declaração de método virtual e a definição de outro.NET idioma é uma combinação de uma declaração de método abstrato e de uma definição separada, com um a default palavra-chave ou o override palavra-chave. Para mais informações e exemplos, consulte Métodos (F#).

Uma classe é considerada abstrata somente se houver métodos abstratos que são declarados, mas não definidos. Portanto, classes que possuem métodos abstratos não são classes abstratas necessariamente. A menos que uma classe tem undefined métodos abstratos, não use o AbstractClass atributo.

Na sintaxe anterior, accessibility-modifier pode ser public, private ou internal. Para obter mais informações, consulte Controle de acesso (F#).

Como ocorre com outros tipos, classes abstratas podem ter uma classe base e uma ou mais interfaces de base. Cada classe base ou interface é exibido em uma linha separada, juntamente com o inherit palavra-chave.

A definição de tipo de uma classe abstrata pode conter membros totalmente definidos, mas também pode conter membros abstratos. A sintaxe para membros abstratos é mostrada separadamente na sintaxe anterior. Essa sintaxe, o type signature de um membro é uma lista que contém o parâmetro tipos em ordem e os tipos de retorno, separada por -> tokens e/ou * tokens conforme apropriado para curried e parâmetros de tupled. A sintaxe para assinaturas de tipo de membro abstract é a mesma usada nos arquivos de assinatura e que o mostrado pela IntelliSense no Editor de código de Visual Studio.

Exemplo

O código a seguir ilustra uma classe abstrata Shape, que tem duas classes derivadas de non-abstract, Square e Circle. O exemplo mostra como usar propriedades, métodos e classes abstratas. No exemplo, a classe abstrata Shape representa os elementos comuns de círculo de entidades concreta e quadrado. Os recursos comuns de todas as formas (em um sistema de coordenadas bidimensional) são abstraídos para fora na Shape classe: a posição na grade, um ângulo de rotação e as propriedades de área e perímetro. Esses podem ser substituídas, exceto para a posição, o comportamento dos quais formas individuais não podem alterar.

Pode do método de rotação ser substituído, como na Circle classe, que é a rotação invariável por causa da simetria. Portanto, o Circle classe, o método de rotação é substituído por um método que não faz nada.

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

Consulte também

Referência

Classes (F#)

Métodos (F#)

Propriedades (F#)

Conceitos

Membros (F#)