Methods Fundamentals

Introduction

You can create a function in the body of a class. Such a member function is also called a method. A method is primarily created the exact same way as a regular function of a code file. Because a method is created in a class, its creation must be indented, and its body must be indented below the function name. In the body of the function, you can write the desired code. Here is an example:

type Book() =
    let read _ =
        printfn "You must read a book today."

Doing a Calling

Remember that, other than a function, to perform an action in a class, you can create a do section. In that do section, you can call a method. Here is an example:

type Book() =
    let read _ =
        printfn "You must read a book today."
        
    do
        read()

Also remember that, to use a class, you must declare a variable of the class. Here is an example:

type Book() =
    let read _ =
        printfn "You must read a book today."
        
    do
        read()
        
let a = Book()

Also remember that, when creating an object, you can precede the name of the class with the new operator. Here is an example:

type Vehicle() =
    . . .

let car = new Vehicle();

Other than these observations, you can create as many methods as you want and each can perform as many actions as necessary.

A Method and Local Variables

The same way a do binding does, a method has direct access to the variables declared locally in the class. In the body of a method, to access a let variable declared in the body of a class, simply use the name of the variable. Here is an example of a method that displays the values of the member variables of a class:

type Property() =
    let number = 927_571_395
    let beds   = 3
    let baths  = 2.50f
    let price  = 397_495

    let show _ =
        printfn "Property Information"
        printfn "---------------------------"
        printfn "Property #:    %i" number
        printfn "Bedrooms:      %d" beds
        printfn "Bathrooms:     %0.2f" baths
        printfn "Market Value:  %d" price

    do
        show()

let house = Property()

printfn "=========================="

This would produce:

Property Information
---------------------------
Property #:    927571395
Bedrooms:      3
Bathrooms:     2.50
Market Value:  397495
==========================

Press any key to close this window . . .

A Method as an Accessible Member

When creating a method, if you want to be able to access it outside a class, you can create that method as a member. Once again, the formula to follow is:

member self-identifier | class-name.method-name([parameter(s)) = body

Start with the member keyword and an empty space. Then add a self-identifier that follows the description we saw for properties. This means that a self-identifier can be a letter, a word that starts with a letter, such as this, self, me, my, or else. You can also use the name of the class for the self-identifier. After the self-identifier, add a period and the desired name of the method. The name should start in uppercase. The name of the member function is folllowed by parentheses. If you need to pass arguments to the method, add them inside the parentheses. The parentheses are followed by = and the body of the method. The body is used to define what the method does. Here is an example of a simple member method that displays text:

type Vehicle() =
    member this.Show() =
        printfn "Vehicle Information"

As seen with regular methods, a member method can access the let variables of the class by their names. Here are examples:

type Property() =
    let number = 927_571_395
    let beds   = 3
    let baths  = 2.50f
    let price  = 397_495

    member me.Show _ =
        printfn "Property Information"
        printfn "---------------------------"
        printfn "Property #:    %i" number
        printfn "Bedrooms:      %d" beds
        printfn "Bathrooms:     %0.2f" baths
        printfn "Market Value:  %d" price

Once again, remember that, to use a class, you must first declare a variable and initialize it with the name of the class. To call a member method, type the name of the variable, a period, the name of the method, and (you must) add the parentheses. Here is an example:

type Property() =
    let number = 927_571_395
    let beds   = 3
    let baths  = 2.50f
    let price  = 397_495

    member me.Show _ =
        printfn "Property Information"
        printfn "---------------------------"
        printfn "Property #:    %i" number
        printfn "Bedrooms:      %d" beds
        printfn "Bathrooms:     %0.2f" baths
        printfn "Market Value:  %d" price

let house = Property()

house.Show()
printfn "=========================="

A Class with Private and Public Members

In a class, you can declare regular variables or create regular functions with the let keyword. You can also create member objects. If you decide to mix regular let members (variables and functions) and members created with the member keyword, the let members must be created before the members created with the member keywords.

Remember that both a regular member function (created with the let keyword) and a member method can access let members by their names. A regular member function cannot access the members declared or created with the member keyword.

In the body of a member method, to access a member declared or created with the member keword, you must type the self-identifier of the member, a period, and the desired member. Here are examples:

type Address() =
    member self.Recipient = "Melissa Durand"
    member self.StreetNumberAndName = "13828 Anderson Briar Road"
    member self.Suite = "D12"
    member self.City = "Lake City"
    member self.State = "South Carolina"
    member self.ZIPCode = "29560"
    
    member self.Show _ =
        printfn "Personal Address"
        printfn "------------------------------------------"
        printfn "Recipient #: %s" self.Recipient
        printfn "Address:     %s %s" self.StreetNumberAndName self.Suite
        printfn "City:        %s" self.City
        printfn "State:       %s" self.State
        printfn "ZIP-Code:    %s" self.ZIPCode

let adrs = Address()

adrs.Show()

printfn "=========================================="

A Method With a Parameter

To perform its operation(s), a method may require one or more values that would be supplied to it one way or another. As done for regular functions, if you are passing just one parameter, write its name after the name of the method. Then, in the body of the method, use the parameter as you see fit. When calling the method, pass the desired (appropriate) value. Here is an example:

type HotelRoom(number, roomType, rate) =
    member this.RoomNumber = number
    member this.RoomType = roomType
    member this.DailyRate = rate
    member this.CalculateInvoice days =
        float days * rate

let room = HotelRoom(104, "Bedroom", 95.50)
let days = 3
let total = room.CalculateInvoice days

printfn "Hotel Room"
printfn "-----------------------"
printfn "Room #:        %d" room.RoomNumber
printfn "Room Type:     %s" room.RoomType
printfn "Daily Rate:    %0.02f" room.DailyRate
printfn "Days:          %d" days
printfn "Total Invoice: %0.02f" total
printfn "-----------------------"

This would produce:

Hotel Room
-----------------------
Room #:        104
Room Type:     Bedroom
Daily Rate:    95.50
Days:          3
Total Invoice: 286.50
-----------------------
Press any key to continue . . .

If you want to indicate the type of the parameter, include it in parentheses with : and its type. Here is an example:

type HotelRoom(number, roomType, rate) =
    member this.RoomNumber = number
    member this.RoomType = roomType
    member this.DailyRate = rate
    member this.CalculateInvoice days =
        float days * rate

let room = HotelRoom(104, "Bedroom", 95.50)
let days = 3
let total = room.CalculateInvoice (days : int)

printfn "Hotel Room"
printfn "-----------------------"
printfn "Room #:        %d" room.RoomNumber
printfn "Room Type:     %s" room.RoomType
printfn "Daily Rate:    %0.02f" room.DailyRate
printfn "Days:          %d" days
printfn "Total Invoice: %0.02f" total
printfn "-----------------------"

A Method With Parameters

A method can use more than one parameter. As done for functions, make the list of parameters separated by empty spaces after the name of the method. Here is an example:

type HotelRoom(number, roomType, rate) =
    member this.RoomNumber = number
    member this.RoomType = roomType
    member this.DailyRate = rate
    member this.CalculateInvoice days phoneCharge discount =
        (float days * rate) + phoneCharge - (float days * rate * discount / 100.00)

let room = HotelRoom(104, "Bedroom", 95.50)
let days = 3
let phoneUse = 12.48
let total = room.CalculateInvoice 3 12.48 0.00

printfn "Hotel Room"
printfn "-----------------------"
printfn "Room #:        %d" room.RoomNumber
printfn "Room Type:     %s" room.RoomType
printfn "Daily Rate:    %0.02f" room.DailyRate
printfn "Days:          %d" days
printfn "Phone Charge:  %0.02f" phoneUse
printfn "Total Invoice: %0.02f" total
printfn "-----------------------"

This would produce:

Hotel Room
-----------------------
Room #:        104
Room Type:     Bedroom
Daily Rate:    95.50
Days:          3
Phone Charge:  12.48
Total Invoice: 298.98
-----------------------
Press any key to continue . . .

Named Arguments

When calling a method, you must provide the appropriate arguments in the order their parameters appear on the method. When calling the method, you can specify the arguments in an order of your choice. To do that, when creating the method, include its parameters in the parentheses and separate the parameters with commas. Here is an example:

type HotelRoom() =
    member this.CalculateInvoice(days, phoneCharge, discountApplied, discountRate) =
        (float days * rate) + phoneCharge - (float days * rate * discount / 100.00)

When calling the method, instead of simply listing the values of its arguments, add some parentheses to the method call. In the parentheses, type the name of a parameter, followed by =, and followed by its value; separate them with commas. Here is an example:

type HotelRoom(number, roomType, rate) =
    member this.RoomNumber = number
    member this.RoomType = roomType
    member this.DailyRate = rate
    member this.CalculateInvoice(days, phoneCharge, discountApplied, discountRate) =
        if discountApplied = true then
            (float days * rate) + phoneCharge - (float days * rate * discountRate / 100.00)
        else
            (float days * rate) + phoneCharge

let room = HotelRoom(104, "Bedroom", 95.50)
let days = 3
let phoneUse = 12.48
let total = room.CalculateInvoice(discountApplied = true, days = 3, discountRate = 20.00, phoneCharge = 12.48)

printfn "Hotel Room"
printfn "-----------------------"
printfn "Room #:        %d" room.RoomNumber
printfn "Room Type:     %s" room.RoomType
printfn "Daily Rate:    %0.02f" room.DailyRate
printfn "Days:          %d" days
printfn "Phone Charge:  %0.02f" phoneUse
printfn "Total Invoice: %0.02f" total
printfn "-----------------------"

This would produce:

Hotel Room
-----------------------
Room #:        104
Room Type:     Bedroom
Daily Rate:    95.50
Days:          3
Phone Charge:  12.48
Total Invoice: 241.68
-----------------------
Press any key to continue . . .

If you decide to simply provide the arguments to the method without using the names of the parameters, you must still use the parentheses and provide the argumens in the order of their parameters.

You can use the same technique of named arguments in the parentheses of the constructor used to create an object when declaring such a variable. Here is an example:

type HotelRoom(number, roomType, rate) =
    member this.RoomNumber = number
    member this.RoomType = roomType
    member this.DailyRate = rate
    member this.CalculateInvoice(days, phoneCharge, discountRate) =
        (float days * rate) + phoneCharge - (float days * rate * discountRate / 100.00)

let room = HotelRoom(roomType = "Conference Room", rate = 98.80, number = 110)
let days = 1
let phoneUse = 0.00
let total = room.CalculateInvoice(days = 3, discountRate = 0.00, phoneCharge = 12.48)

printfn "Hotel Room"
printfn "-----------------------"
printfn "Room #:        %d" room.RoomNumber
printfn "Room Type:     %s" room.RoomType
printfn "Daily Rate:    %0.02f" room.DailyRate
printfn "Days:          %d" days
printfn "Phone Charge:  %0.02f" phoneUse
printfn "Total Invoice: %0.02f" total
printfn "-----------------------"

This would produce:

Hotel Room
-----------------------
Room #:        110
Room Type:     Conference Room
Daily Rate:    450.00
Days:          1
Phone Charge:  0.00
Total Invoice: 450.00
-----------------------
Press any key to continue . . .

The Staticity of a Class

Introduction

A variable declared from a class is also called an instance of the class. In the same way, you can declare various instances of the same class as necessary:

type Vehicle(tag : string, make : string, model : string, yr : int) =
    member this.TagNumber = tag
    member this.Make = make
    member this.Model = model
    member this.Year = yr

let sedan = new Vehicle("927748", "Toyota", "Corolla", 2004)
let suv = new Vehicle("297M660", "Honda", "Pilot", 2010)

Each one of these instances gives you access to the members of the class but each instance holds the particular values of the members of its instance. Consider the results of the following program:

type Vehicle(tag : string, make : string, model : string, yr : int) =
    member this.TagNumber = tag
    member this.Make = make
    member this.Model = model
    member this.Year = yr

let sedan = new Vehicle("927748", "Toyota", "Corolla", 2004)
let suv = new Vehicle("297M660", "Honda", "Pilot", 2010)

printfn "Vehicle Information"
printfn "-------------------------"
printfn "       Sedan\tSUV"
printfn "-------------------------"
printfn "Tag #: %s\t%s" sedan.TagNumber suv.TagNumber
printfn "Make:  %s\t%s" sedan.Make suv.Make
printfn "Model: %s\t%s" sedan.Model suv.Model
printfn "Year:  %d\t\t%d" sedan.Year suv.Year

This would produce:

Vehicle Information
-------------------------
       Sedan	SUV
-------------------------
Tag #: 927748	297M660
Make:  Toyota	Honda
Model: Corolla	Pilot
Year:  2004		2010

All of the variables and members of classes we have used so far are referred to as instance members because, in order to access them, you must have an instance of a type or of a class declared where you want to access them.

In your application, you can declare a variable and refer to it regardless of which instance of an object you are using. Such a variable is called static. A static member of a class is internally accessed as soon as the program starts running. Because a static member is not tied to a particular instance of a class, a static member cannot use a self-identifier.

A Static Variable

To declare a member variable of a class as static, type the static keyword on the left of let. Here is an example:

type Book() =
    static let title = string

In the same way, you can declare as many static member variables as you want in a class. Remember that let members are always private, so there is no reason to apply an access level to a static member.

In a class, you can access a static member variable as you would a non-static member. If you plan to change the value of the variable, you should first declare it using the mutable keyword. Here is an example:

type Book() =
    static let mutable title : string = ""
    
    do
        title <- "Psychology and Human Evolution"
        printfn "Title: %s" title

let bk = new Book();

Static Methods

Introduction

A normal method of a class can access a (the) static member(s) of the same class. Here is an example:

type Book() =
    static let mutable title : string = ""
    
    member this.Initialize() =
        title <- "Psychology and Human Evolution"
        printfn "Title: %s" title
        
let bk = new Book();

bk.Initialize()

In the same way, you can declare a combination of static and non-static variables as you see fit. Here is an example:

type Book() =
    static let mutable title : string = ""
    let mutable copyrightYear : int = 0
    
    member this.Initialize() =
        title <- "Psychology and Human Evolution"
        copyrightYear <- 2010
        
        printfn "Title:          %s" title
        printfn "Copyright Year: %d" copyrightYear
        
let bk = new Book();

bk.Initialize()

Statically doing Something

We already know that the do keyword can be used to perform an operation in a class. The action(s) of the do section is(are) performed when you declare a variable for the class. If you want the action(s) to take place whether an object is formally created or not, precede the do keyword with static. The member variables accessed in the do section have to be static. Here is an example:

type Vehicle() =
    static let mutable tagNumber : string = ""
    static let mutable year : int = 1960
    
    static do
        tagNumber <- "929384" 
        year <- 2010
        
        printfn "Title: %s" tagNumber
        printfn "Year:  %d" year
        
let car = new Vehicle();

This would produce:

Title: 929384
Year:  2010

Of course, you can create different do and static do sections in your class. Here is an example:

type Vehicle() =
    static let mutable tagNumber : string = ""
    let mutable make : string = ""
    let mutable model : string = ""
    static let mutable year : int = 1960
    
    do
        make <-  "Honda"
        model <- "Accord"
        
        printfn "Make:  %s" make
        printfn "Model: %s" model
        
    static do
        tagNumber <- "929384" 
        year <- 2010
        
        printfn "Title: %s" tagNumber
        printfn "Year:  %d" year
        
let car = new Vehicle();

If you do this, the static do section would be accessed first. The above program would produce:

Title: 929384
Year:  2010
Make:  Honda
Model: Accord

A Static Method

Like a member variable, a method of a class can be defined as static. Such a method can access any member of the class.

To create a static method, type the static keyword to the left of the member keyword. Remember that the method cannot use a self-identifier. Here is an example:

type Book() =
    static member Initialize() = . . .

The way a static method accesses a member variable depends on how the member was created. Static members are directly accessible in the body of a static method, with just the name of the static member. Here is an example:

type Book() =
    static let mutable title : string = ""
    
    static member Initialize() =
        title <- "Psychology and Human Evolution"

        printfn "Title: %s" title

Outside the class, to access a static member, don't declare a variable for the class. Simply use the name of the class and access the static method using the period operator. Here is an example:

type Book() =
    static let mutable title : string = ""
    
    static member Initialize() =
        title <- "Psychology and Human Evolution"

        printfn "Title:          %s" title 

Book.Initialize()

Static Classes

Like a variable or a method, a class can be considered static. A static class is a class whose members are accessed without creating an instance of the class. Also, all members of a static class are created as static.


Previous Copyright © 2014-2024, FunctionX Monday 14 February 2022 Next