Compartilhar via


Métodos (F#)

A método é uma função que está associada um tipo. Na programação orientada a objeto, os métodos são usados para expor e implementar a funcionalidade e o comportamento de objetos e tipos.

// Instance method definition.
[ attributes ]
member [inline] self-identifier.method-name parameter-list [ : return-type ]=
    method-body

// Static method definition.
[ attributes ]
static member [inline] method-name parameter-list [ : return-type ]=
    method-body

// Abstract method declaration or virtual dispatch slot.
[ attributes ]
abstract member self-identifier.method-name : type-signature

// Virtual method declaration and default implementation.
[ attributes ]
abstract member [inline] self-identifier.method-name : type-signature
[ attributes ]
default member [inline] self-identifier.method-name parameter-list[ : return-type ] =
    method-body

// Override of inherited virtual method.
[ attributes ]
override member [inline] self-identifier.method-name parameter-list [ : return-type ]=
    method-body

Comentários

Na sintaxe anterior, você pode ver as várias formas de definições e declarações de método. No mais corpos de método, uma quebra de linha segue o sinal de igual (=) e o corpo do método inteiro é recuado.

Atributos podem ser aplicados a qualquer declaração de método. Eles precedem a sintaxe de uma definição de método e geralmente são listados em uma linha separada. Para obter mais informações, consulte Atributos (F#).

Métodos podem ser marcados inline. Para obter informações sobre inline, consulte Funções embutidas (F#).

Os métodos de in-line não podem ser usado recursivamente dentro do tipo; não é necessário usar explicitamente a rec palavra-chave.

Métodos de instância

Métodos de instância são declarados com o member palavra-chave e um self-identifier, seguido por um ponto (.) e o nome do método e parâmetros. Como é o caso para let ligações, o parameter-list pode ser um padrão. Normalmente, você coloque método aparecem de parâmetros em parênteses em um formulário de tupla, que é os modo como os métodos F# quando eles são criados em outros.Idiomas do NET Framework. Entretanto, o formulário curried (parâmetros separados por espaços) também é comum e outros padrões são suportados também.

O exemplo a seguir ilustra a definição e uso de um método de instância de non-abstract.

type SomeType(factor0: int) =
   let factor = factor0
   member this.SomeMethod(a, b, c) =
      (a + b + c) * factor

   member this.SomeOtherMethod(a, b, c) =
      this.SomeMethod(a, b, c) * factor

Dentro de métodos de instância, não use o identificador de auto-aos campos de acesso definidos usando ligações let. Use o identificador de auto-ao acessar outros membros e propriedades.

Métodos estáticos

A palavra-chave static é usado para especificar que um método pode ser chamado sem uma instância e não associado com uma instância do objeto. Caso contrário, os métodos são métodos de instância.

O exemplo na próxima seção mostra campos declarados com o let palavra-chave, os membros da propriedade declarados com o member palavra-chave e um método estático declarado com o static palavra-chave.

O exemplo a seguir ilustra a definição e uso de métodos estáticos. Suponha que essas definições de método estão na SomeType a classe na seção anterior.

static member SomeStaticMethod(a, b, c) =
   (a + b + c)

static member SomeOtherStaticMethod(a, b, c) =
   SomeType.SomeStaticMethod(a, b, c) * 100

Métodos abstratos e virtuais

A palavra-chave abstract indica que um método tem um slot de despacho virtual e pode não ter uma definição de classe a. A slot de despacho virtual é uma entrada em uma tabela mantida internamente das funções que é usada em tempo de execução para procurar a função virtual chama um tipo de orientada a objeto. O mecanismo de despacho virtual é o mecanismo que implementa polimorfismo, um recurso importante da programação orientada a objeto. É de uma classe que tenha pelo menos um método abstrato sem uma definição de um classe abstrata, que significa que nenhuma instância pode ser criada dessa classe. Para obter mais informações sobre classes abstratas, consulte Classes abstratas (F#).

Declarações de método abstract não incluem um corpo de método. Em vez disso, o nome do método é seguido de dois pontos (:) e uma assinatura de tipo para o método. A assinatura de tipo de um método é o mesmo que o mostrado pela IntelliSense quando você posiciona o ponteiro do mouse sobre um nome de método no Code Editor do Visual Studio, exceto sem nomes de parâmetro. Assinaturas de tipo também são exibidas, o interpretador de FSI. exe, quando você estiver trabalhando de forma interativa. A assinatura de tipo de um método é formada pela listagem de tipos de parâmetros, seguidos do tipo de retorno, com os símbolos de separador apropriado. Os parâmetros curried são separados por - > e os parâmetros de tupla são separados por *. O valor de retorno é sempre separado dos argumentos por a - > símbolo. Parênteses podem ser usados para agrupar os parâmetros complexos, como, por exemplo, quando um tipo de função é um parâmetro, ou para indicar quando uma tupla é tratada como um único parâmetro, em vez de fazê-lo como dois parâmetros.

Você também pode fornecer definições padrão de métodos abstratos, adicionando a definição para a classe e usando o default palavra-chave, como mostrado no bloco de sintaxe neste tópico. Um método abstrato que tem uma definição na mesma classe é equivalente a um método virtual em outros.Idiomas do NET Framework. Se houver uma definição de abstract palavra-chave cria um novo slot de despacho da tabela de função virtual para a classe.

Independentemente, por exemplo, se uma classe base implementa os métodos abstratos, classes derivadas podem fornecer implementações dos métodos abstratos. Para implementar um método abstrato em uma classe derivada, define um método que possui o mesmo nome e assinatura na classe derivada, exceto o uso de override ou default palavra-chave e fornecer o corpo do método. As palavras-chave override e default significa exatamente a mesma coisa. Use override se o novo método substitui a implementação da classe base; Use default Quando você cria uma implementação na mesma classe como a declaração abstrata original. Não use o abstract palavra-chave no método que implementa o método que foi declarado como abstrato em que a classe de base.

O exemplo a seguir ilustra um método abstrato Rotate que tem uma implementação do padrão, o equivalente a um.NET Framework o método virtual.

type Ellipse(a0 : float, b0 : float, theta0 : float) =
    let mutable axis1 = a0
    let mutable axis2 = b0
    let mutable rotAngle = theta0
    abstract member Rotate: float -> unit
    default this.Rotate(delta : float) = rotAngle <- rotAngle + delta

O exemplo a seguir ilustra uma classe derivada, substitui um método de classe base. Nesse caso, a substituição altera o comportamento de forma que o método não fará nada.

type Circle(radius : float) =
    inherit Ellipse(radius, radius, 0.0)
     // Circles are invariant to rotation, so do nothing.
    override this.Rotate(_) = ()

Métodos sobrecarregados

Métodos sobrecarregados são métodos que têm nomes idênticos em um determinado tipo, mas que possuem argumentos diferentes. No F#, os argumentos opcionais são usados normalmente em vez de métodos sobrecarregados. No entanto, os métodos sobrecarregados são permitidos na linguagem, desde que os argumentos estão na forma de tupla, o formulário não curried.

Exemplo: Propriedades e métodos

O exemplo a seguir contém um tipo de exemplos de campos, funções private, propriedades e um método estático.

type RectangleXY(x1 : float, y1: float, x2: float, y2: float) =
    // Field definitions.
    let height = y2 - y1
    let width = x2 - x1
    let area = height * width
    // Private functions.
    static let maxFloat (x: float) (y: float) =
      if x >= y then x else y
    static let minFloat (x: float) (y: float) =
      if x <= y then x else y
    // Properties.
    // Here, "this" is used as the self identifier,
    // but it can be any identifier.
    member this.X1 = x1
    member this.Y1 = y1
    member this.X2 = x2
    member this.Y2 = y2
    // A static method.
    static member intersection(rect1 : RectangleXY, rect2 : RectangleXY) =
       let x1 = maxFloat rect1.X1 rect2.X1
       let y1 = maxFloat rect1.Y1 rect2.Y1
       let x2 = minFloat rect1.X2 rect2.X2
       let y2 = minFloat rect1.Y2 rect2.Y2
       let result : RectangleXY option =
         if ( x2 > x1 && y2 > y1) then
           Some (RectangleXY(x1, y1, x2, y2))
         else
           None
       result

// Test code.
let testIntersection =
    let r1 = RectangleXY(10.0, 10.0, 20.0, 20.0)
    let r2 = RectangleXY(15.0, 15.0, 25.0, 25.0)
    let r3 : RectangleXY option = RectangleXY.intersection(r1, r2)
    match r3 with
    | Some(r3) -> printfn "Intersection rectangle: %f %f %f %f" r3.X1 r3.Y1 r3.X2 r3.Y2
    | None -> printfn "No intersection found."

testIntersection

Consulte também

Conceitos

Membros (F#)