Методы и функции

Последнее обновление: 11.12.2023

Классы может иметь некоторое поведение, то есть определять некоторые действия с помощью методов. Метод представляет функцию, которая ассоциирована с определенным типом.

В различие от типа методов их определение может отличаться. В данном случае мы пока рассмотрим методы объектов. В общем случае они определяются в следующем виде:

member this.имя_метода параметры [ : тип_результата ] = действия_метода

Вначале идет ключевое слово member. Далее идет ключевое слово this. Оно указывает, что этот метод определяет поведение объекта и его можно вызвать через имя объекта. После this через точку указывается собственно имя метода.

В остальном метод похож на обычную функцию. После имени метода также определяются параметры, для которых опционально можно определить тип данных. И также можно опционально указать через двоеточие тип возвращаемого результата метода. А после символа "равно" (=) указываются действия, выполняемые методов.

Например, определим простейший метод:

type Person (name, age) = 
    member this.SayHi() = printfn "Hi!"

let tom = Person("Tom", 37)
tom.SayHi()

Здесь метод называется SayHi. Он имеет только один параметр - значение unit (то есть фактически не имеет параметров). Все, что делает этот метод, это выводит на консоль строку с приветствием "Hi".

Имея объект данного типа, через имя объекта мы можем обратиться к методу. Для обращения к методу объекта сначала идет имя объекта (в примере выше - "tom") и через точку указывает имя вызываемого метода:

tom.SayHi()

В остальном вызов метода происходит также как к обычной функции - мы также должны передать значения для его параметров и также можем получить его результат.

В итоге при выполнении данной программы на консоль будет выведена строка "Hi".

Стоит отметить, что обычно названия методов начинаются с большой буквы.

Также стоит отметить, что через this мы можем обращаться к функционалу объекта внутри класса. Здесь же мы никак this не используем, поэтому вместо него можно использовать прочерк:

type Person (name, age) = 
    member _.SayHi() = printfn "Hi!"

let tom = Person("Tom", 37)
tom.SayHi()

Обращение к параметрам первичного конструктора

Методы объектов имеют доступ к параметрам первичным конструкторов. Например, задействуем значения параметров в методах:

type Person (name, age) = 
    member _.SayHi() = printfn $"Hi! My name is {name}"
    member _.Print() = printfn $"Name: {name}  Age: {age}"

let tom = Person("Tom", 37)
tom.SayHi()
tom.Print()

Консольный вывод программы:

Hi! My name is Tom
Name: Tom  Age: 37

Методы с параметрами

Методы классов, как и функции, могут принимать параметры. Передача параметров методам выполняется как и в целом в случае с функциями:

type Person (name, age) = 
    member _.Say text = printfn $"{name} говорит: `{text}`"
 
let tom = Person("Tom", 37)
tom.Say "Привет"    // Tom говорит: `Привет`

И также мы можем типизировать параметры:

type Person (name, age) = 
    member _.Say (text:string) = printfn $"{name} говорит: `{text}`"

Получение результата метода

Методы, как и обычные функции, могут возвращать результат:

type Person (name, age) = 
    member _.GetInfo() = $"Name: {name}  Age: {age}"

let tom = Person("Tom", 37)
let tomInfo = tom.GetInfo()     // получим результат метода
printfn "%s" tomInfo

Здесь метод GetInfo() возвращает строку с общей информацией об объекте:

member _.GetInfo() = $"Name: {name}  Age: {age}"

Также мы можем типизировать тип результата:

member _.GetInfo() : string = $"Name: {name}  Age: {age}"

Модификаторы доступа

Метод может иметь модификатор доступа, который ограничивает контекст применения метода. Модификатор доступа указывается после ключевого слова member и перед именем метода:

type Person (name, age) = 
    member internal _.SayHi() = printfn $"Hi! My name is {name}"
    member private _.Print() = printfn $"Name: {name}  Age: {age}"
 
let tom = Person("Tom", 37)
tom.SayHi()
// tom.Print()	- метод Print приватный и доступен только внутри класса

Приватные методы доступны только внутри своего класса. Так, в примере выше метод SayHi доступен в рамках текущего проекта, а метод Print только внутри класса Person.

let-привязка функций

Для определения поведения классы, наряду с методами, также могут определять функции с помощью оператора let:

type Person (name, age) = 
    
    let getYearOfBirth() =  System.DateTime.Now.Year - age  // приватная функция
    member _.Print() = printfn $"Имя: {name}  Год рождения: { getYearOfBirth() }"
 
let tom = Person("Tom", 37)
tom.Print()

// let year = tom.getYearOfBirth() // так нельзя - функция getYearOfBirth вне класса Person недоступна

Здесь в классе Person определена функция getYearOfBirth(), которая вычисляет год рождения на основе переданного возраста пользователя через параметр age. Для вычисления года рождения применяется конструкция System.DateTime.Now.Year, которая возвращает текущий год.

Однако стоит учитывать, что функции классов, определенные с помощью let, достуны только внутри своего класса. То есть они аналогичные приватным методам. Поэтому мы можем их использовать внутри класса для каких-то промежуточных вычислений, например, внутри методов:

member _.Print() = printfn $"Имя: {name}  Год рождения: { getYearOfBirth() }"

Но вне класса они недоступны:

// let year = tom.getYearOfBirth() // функция getYearOfBirth вне класса Person недоступна
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850