OOP in F# - Define and Implement Classes, Abstract Classes, and Interfaces
OOP in F# - Define and Implement Classes, Abstract Classes, and Interfaces
Here's an overview of OO concepts in F# which are particularly useful for interacting with C# code.
Join the DZone community and get the full member experience.
Join For FreeAccess over 20 APIs and mobile SDKs, up to 250k transactions free with no credit card required
Even though F# is a functional language, it also provides ways to build applications in an object oriented way. When interacting with C# libraries, it is very useful since C# is object oriented by nature.
Today, I would like to show you how you can define and build classes in an object oriented way. This post is composed of three parts:
1 - Classes
2 - Abstract Classes / Interfaces
3 - Inheritance
1. Classes
Defining classes is the same as defining record type, by using the keyword type
. Classes can have constructors
and members
which can either be a function
or a property
.
type MyType(name) =
let mutable name = name
do
() // do some side effect
member self.DoSomething() =
()
member self.PropName
with get() = name
and set value =
name <- value
new() =
new MyType("default name")
let mytype = new MyType()
There is a primary constructor defined on the class name type MyType(name)
. Members can either be a function like DoSomething
or a property with a getter and setter like PropName
. All side effects must be performed in a do
statement before the members. Extra constructors can be defined after the members using the new
syntax. Lastly, any settable properties can be set directly from the empty constructor.
2. Abstract Classes/Interfaces
Interfaces are defined the same way as classes with type
with abstract
members.
type IMyInterface =
abstract DoSomething: unit -> unit
abstract PropName: string with get, set
They can define functions like DoSomething
or properties like PropName
.
Abstract classes can provide a default implementation for certain members.
[<AbstractClass>]
type MyTypeBase() =
member self.DoSomething() = ()
abstract PropName: string with get, set
abstract SomeMethod: unit -> unit
default self.SomeMethod() = ()
They must be marked as AbstractClass
. default
implementation of abstract
members can be provided like we did for SomeMethod
. with get, set
is used to define abstract properties with getter and setter.
3. Inheritance
Inheritance of abstract classes is done via the inherit
keyword.
type MyType'(name) =
inherit MyTypeBase()
let mutable name = name
do
base.SomeMethod()
member self.DoSomething() =
base.DoSomething()
override self.PropName
with get() = name
and set value =
name <- value
new() =
new MyType'("default name")
And implementation of interface is done via explicit implementation.
type MyType(name) =
let mutable name = name
interface IMyInterface with
member self.DoSomething() = ()
member self.PropName
with get() = name
and set value =
name <- value
new() =
new MyType("default name")
is used to implement interfaces. To implement multiple interfaces, repeat the
interface ... withinterface ... with
notation.
Another way to implement interfaces is via expression.
type IMyInterface' =
abstract DoSomething: unit -> unit
let x =
{ new IMyInterface' with
member self.DoSomething() = () }
x.DoSomething()
This way of implementing interfaces is very useful when interacting with C# libraries for functions which require arguments implementing certain interfaces.
Conclusion
This was a quick look at how to use F# in an OOP way. We saw how to define and implement classes, abstract classes, and interfaces. F# also provides a neat way to implement interfaces in expression. I hope you enjoyed reading this post as much as I enjoyed writing it. If you have any comments, feel free to hit me on Twitter @Kimserey_Lam. See you next time!
#1 for location developers in quality, price and choice, switch to HERE.
Published at DZone with permission of Kimserey Lam , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}