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#).
Métodos não-inline 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 de um ponto (.) e o nome do método e parâmetros.Como é o caso de let ligações, o parameter-list pode ser um padrão.Normalmente, você coloque método parâmetros entre parênteses em um formulário de tupla, que é os modo como os métodos aparecer em F#, quando eles são criados em outros.Idiomas do NET Framework.No entanto, 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 não-abstrata.
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 está associado 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, membros da propriedade declarada 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 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 na classe.A slot 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#).
Método abstract declarações 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 por 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 pelo intérprete, 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 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, o abstract palavra-chave cria um novo slot de despacho da tabela de função virtual para a classe.
Independentemente de se uma classe base implementa os métodos abstratos, classes derivadas podem fornecer implementações de 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 do override ou default palavra-chave e fornecer o corpo do método.As palavras-chave override e default exatamente o mesmo significado.Use override se o novo método substitui uma implementação de 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 na classe base.
O exemplo a seguir ilustra um método abstrato Rotate que tem uma implementação do padrão, o equivalente a um.Método virtual do NET Framework.
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 que substitui um método de classe base.Nesse caso, a substituição altera o comportamento para 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, não curried do formulário.
Exemplo: Propriedades e métodos
O exemplo a seguir contém um tipo de exemplos de funções privadas, campos, 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