{"id":982,"date":"2013-12-22T23:59:35","date_gmt":"2013-12-22T23:59:35","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=982"},"modified":"2013-12-22T23:59:35","modified_gmt":"2013-12-22T23:59:35","slug":"interfaces-and-classes-in-f","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/interfaces-and-classes-in-f\/","title":{"rendered":"Interfaces and Classes in F#"},"content":{"rendered":"<p><strong>Interfaces<\/strong><\/p>\n<p>Interfaces are declared in a similar fashion to classes but with only abstract members, for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype ICalculator =\r\n    abstract member Add : int -&gt; int -&gt; int\r\n<\/pre>\n<p><strong>Classes<\/strong><\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Calculator() =\r\n    member this.Add a b = a + b\r\n<\/pre>\n<p>Here we declared a constructor with no arguments, but we could also declare a constructor which takes arguments, such as <\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Calculator(a, b) =\r\n        member this.Add = a + b\r\n<\/pre>\n<p>We can also declare the constructors in the following manner<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Calculator1 =\r\n        new () = {}\r\n        member this.Add = a + b\r\n\r\ntype Calculator2 =\r\n        new (a, b) = { (* do something with the values *) }\r\n        member this.Add = a + b\r\n<\/pre>\n<p>Leading on from this way of declaring constructors, we can also declare multiple constructors in the following manner<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype SomeClass =\r\n    val data : string\r\n    new () = { data = &quot;undefined&quot;}\r\n    new (d) = { data = d }\r\n<\/pre>\n<p>Here we&#8217;ve declared a default constructor and one which takes a single argument.<\/p>\n<p>or implementing the previously declared ICalculator we have<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Calculator() =\r\n    interface ICalculator with\r\n        member this.Add a b = a + b\r\n<\/pre>\n<p>To access the Add method we need to cast our value to the specific interfaces, for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet calc = new Calculator()\r\n(calc :&gt; ICalculator).Add 2 3\r\n<\/pre>\n<p>The :> is the cast operator.<\/p>\n<p>We can also implement an interface in an anonymous class, for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet calculator() =\r\n   {\r\n      new ICalculator with\r\n         member this.Add a b = a + b\r\n   }\r\n<\/pre>\n<p><strong>Inheritance<\/strong><\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Calculator() =\r\n   member this.Add a b = a + b\r\n\r\ntype NewCalculator() = \r\n   inherit Calculator()   \r\n<\/pre>\n<p><strong>Virtual functions<\/strong><\/p>\n<p>To declare a function as virtual we need to both declare it as abstract and create a default implementation, for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype MyClass() = \r\n   abstract member myfunction : unit -&gt; unit\r\n   default u.myfunction() = printfn &quot;hello&quot;\r\n<\/pre>\n<p><em>Note: the &#8220;u.&#8221; part of the above is a self identifier. Unlike C# which has the implicit &#8220;this&#8221; identifier, we can define whatever name we wish for the self identifier<\/em><\/p>\n<p>We can define a self identifier at the class level using<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype MyClass() as myself = \r\n   abstract member myfunction : unit -&gt; unit\r\n   default myself.myfunction() = printfn &quot;hello&quot;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Interfaces Interfaces are declared in a similar fashion to classes but with only abstract members, for example type ICalculator = abstract member Add : int -&gt; int -&gt; int Classes type Calculator() = member this.Add a b = a + b Here we declared a constructor with no arguments, but we could also declare a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-982","post","type-post","status-publish","format-standard","hentry","category-f"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=982"}],"version-history":[{"count":11,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/982\/revisions"}],"predecessor-version":[{"id":993,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/982\/revisions\/993"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}