Классы может иметь некоторое поведение, то есть определять некоторые действия с помощью методов. Метод представляет функцию, которая ассоциирована с определенным типом.
В различие от типа методов их определение может отличаться. В данном случае мы пока рассмотрим методы объектов. В общем случае они определяются в следующем виде:
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:
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 недоступна