Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Un método es una función asociada a un tipo. En la programación orientada a objetos, los métodos se usan para exponer e implementar la funcionalidad y el comportamiento de objetos y tipos.
Sintaxis
// 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 method-name : type-signature
// Virtual method declaration and default implementation.
[ attributes ]
abstract member method-name : type-signature
[ attributes ]
default self-identifier.method-name parameter-list [ : return-type ] =
method-body
// Override of inherited virtual method.
[ attributes ]
override self-identifier.method-name parameter-list [ : return-type ] =
method-body
// Optional and DefaultParameterValue attributes on input parameters
[ attributes ]
[ modifier ] member [inline] self-identifier.method-name ([<Optional; DefaultParameterValue( default-value )>] input) [ : return-type ]
Observaciones
En la sintaxis anterior, puede ver las distintas formas de declaraciones y definiciones de método. En cuerpos de método más largos, un salto de línea sigue el signo igual (=) y todo el cuerpo del método se aplica sangría.
Los atributos se pueden aplicar a cualquier declaración de método. Preceden a la sintaxis de una definición de método y normalmente se enumeran en una línea independiente. Para obtener más información, vea atributos de .
Los métodos se pueden marcar como inline. Para obtener información sobre inline, vea Funciones insertadas.
Los métodos no insertados se pueden usar de forma recursiva dentro del tipo; no es necesario usar explícitamente la rec palabra clave .
Métodos de instancia
Los métodos de instancia se declaran con la member palabra clave y un identificador propio, seguidos de un punto (.) y el nombre y los parámetros del método. Como es el caso de let los enlaces, la lista de parámetros puede ser un patrón. Normalmente, se incluyen parámetros de método entre paréntesis en un formulario de tupla, que es la forma en que aparecen los métodos en F# cuando se crean en otros lenguajes de .NET Framework. Sin embargo, el formato currido (parámetros separados por espacios) también es común y también se admiten otros patrones.
En el ejemplo siguiente se muestra la definición y el uso de un método de instancia no abstracta.
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 los métodos de instancia, no use el identificador propio para acceder a los campos definidos mediante let enlaces. Use el identificador propio al acceder a otros miembros y propiedades.
Métodos estáticos
La palabra clave static se usa para especificar que se puede llamar a un método sin una instancia de y no está asociado a una instancia de objeto. De lo contrario, los métodos son métodos de instancia.
En el ejemplo de la sección siguiente se muestran los campos declarados con la let palabra clave , los miembros de propiedad declarados con la member palabra clave y un método estático declarado con la static palabra clave .
En el ejemplo siguiente se muestra la definición y el uso de métodos estáticos. Supongamos que estas definiciones de método están en la SomeType clase de la sección anterior.
static member SomeStaticMethod(a, b, c) =
(a + b + c)
static member SomeOtherStaticMethod(a, b, c) =
SomeType.SomeStaticMethod(a, b, c) * 100
Métodos abstractos y virtuales
La palabra clave abstract indica que un método tiene una ranura de distribución virtual y es posible que no tenga una definición en la clase . Una ranura de distribución virtual es una entrada en una tabla de funciones mantenida internamente que se usa en tiempo de ejecución para buscar llamadas de función virtual en un tipo orientado a objetos. El mecanismo de distribución virtual es el mecanismo que implementa el polimorfismo, una característica importante de la programación orientada a objetos. Una clase que tiene al menos un método abstracto sin una definición es una clase abstracta, lo que significa que no se puede crear ninguna instancia de esa clase. Para obtener más información sobre las clases abstractas, vea Clases abstractas.
Las declaraciones de método abstracto no incluyen un cuerpo del método. En su lugar, el nombre del método va seguido de dos puntos (:) y una firma de tipo para el método . La firma de tipo de un método es la misma que la que muestra IntelliSense al pausar el puntero del mouse sobre un nombre de método en el Editor de Visual Studio Code, excepto sin nombres de parámetro. El intérprete también muestra las firmas de tipo, fsi.exe, cuando se trabaja de forma interactiva. La firma de tipo de un método se forma al enumerar los tipos de los parámetros, seguidos del tipo de valor devuelto, con símbolos separadores adecuados. Los parámetros curriados están separados por -> y los parámetros de tupla están separados por *. El valor devuelto siempre está separado de los argumentos por un -> símbolo. Los paréntesis se pueden usar para agrupar parámetros complejos, como cuando un tipo de función es un parámetro, o para indicar cuándo una tupla se trata como un único parámetro en lugar de como dos parámetros.
También puede proporcionar definiciones predeterminadas de métodos abstractos agregando la definición a la clase y usando la default palabra clave , como se muestra en el bloque de sintaxis de este tema. Un método abstracto que tiene una definición en la misma clase es equivalente a un método virtual en otros lenguajes de .NET Framework. Si existe o no una definición, la abstract palabra clave crea una nueva ranura de distribución en la tabla de funciones virtuales de la clase .
Independientemente de si una clase base implementa sus métodos abstractos, las clases derivadas pueden proporcionar implementaciones de métodos abstractos. Para implementar un método abstracto en una clase derivada, defina un método que tenga el mismo nombre y firma en la clase derivada, excepto use la override palabra clave o default y proporcione el cuerpo del método. Las palabras clave override y default significan exactamente lo mismo. Use override si el nuevo método invalida una implementación de clase base; úselo default cuando cree una implementación en la misma clase que la declaración abstracta original. No use la abstract palabra clave en el método que implementa el método declarado abstract en la clase base.
En el ejemplo siguiente se muestra un método Rotate abstracto que tiene una implementación predeterminada, el equivalente de un método virtual de .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
En el ejemplo siguiente se muestra una clase derivada que invalida un método de clase base. En este caso, la invalidación cambia el comportamiento para que el método no haga nada.
type Circle(radius: float) =
inherit Ellipse(radius, radius, 0.0)
// Circles are invariant to rotation, so do nothing.
override this.Rotate(_) = ()
Métodos sobrecargados
Los métodos sobrecargados son métodos que tienen nombres idénticos en un tipo determinado, pero que tienen argumentos diferentes. En F#, normalmente se usan argumentos opcionales en lugar de métodos sobrecargados. Sin embargo, los métodos sobrecargados se permiten en el lenguaje, siempre que los argumentos estén en forma de tupla, no en forma curriada. En el ejemplo siguiente se muestra:
type MyType(dataIn: int) =
let data = dataIn
member this.DoSomething(a: int) = a + data
member this.DoSomething(a: string) = sprintf "Hello world, %s!" a
let m = MyType(10)
printfn "With int: %d" (m.DoSomething(2)) // With int: 12
printfn "With string: %s" (m.DoSomething("Bill")) // With string: Hello world, Bill!
Argumentos opcionales
F# admite argumentos opcionales para los métodos. Para obtener información detallada sobre las distintas formas de argumentos opcionales disponibles en F#, vea Parámetros opcionales.
Ejemplo: Propiedades y métodos
El ejemplo siguiente contiene un tipo que tiene ejemplos de campos, funciones privadas, propiedades y un 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