{"id":4749,"date":"2017-03-26T19:54:05","date_gmt":"2017-03-26T19:54:05","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=4749"},"modified":"2017-03-26T19:54:05","modified_gmt":"2017-03-26T19:54:05","slug":"scala-classesobjectstraits-a-little-more-in-depth","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/scala-classesobjectstraits-a-little-more-in-depth\/","title":{"rendered":"Scala classes\/objects\/traits a little more in depth"},"content":{"rendered":"<p>Recap on what a class, object and trait are&#8230;<\/p>\n<p>A class is analogous to a C# class which is created on a per instance bases. An object is a singleton, analogous to a static class in C# and a trait can how declarations of functions (without implementations) or include implementations which is analogous to a C# abstract class.<\/p>\n<p>So in summary<\/p>\n\n<table id=\"tablepress-1\" class=\"tablepress tablepress-id-1\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Scala<\/th><th class=\"column-2\">C#<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">class<\/td><td class=\"column-2\">class<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">object<\/td><td class=\"column-2\">static class<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">trait<\/td><td class=\"column-2\">abstract class<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-1 from cache -->\n<p><strong>Class<\/strong><\/p>\n<p>As previously mentioned, a class is a type which we can create an instance of, and cannot have abstract (or non-implemented) functions (see trait for abstract\/interface types)<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nclass Rectangle(width: Int, height: Int) {\r\n  def area = width * height\r\n}\r\n<\/pre>\n<p>and we can extend\/derive from this using the <em>extend<\/em> keyword, giving us<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nclass Square(side: Int) extends Rectangle(side, side) {\r\n}\r\n<\/pre>\n<p><strong>Object<\/strong><\/p>\n<p>As previously stated, an object can be viewed as a static class (in C#), giving us<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nobject ShapeFactory {\r\n  def createSquare(side: Int) = \r\n     new Square(side)\r\n  def createRectangle(width: Int, height: Int) = \r\n     new Rectangle(width, height)\r\n}\r\n<\/pre>\n<p>In use, we do not need to use the <em>new<\/em> keyword (just like C#), so we can use this factory like this<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nval square = ShapeFactory.createSquare(5)\r\nassert(square.area == 25)\r\n<\/pre>\n<p><strong>Trait<\/strong><\/p>\n<p>A trait can be viewed as being analogous to an abstract class. We can have functions with implementations or no implementation so that any class which extends this trait must implement the unimplemented functions. Here&#8217;s a trait with a single abstract function (no implementation) named <em>area<\/em> and an implementation of a function named <em>name<\/em><\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\ntrait Shape {\r\n  def area : Int\r\n  \r\n  def name = &quot;Shape&quot;\r\n}\r\n<\/pre>\n<p>We cannot create a trait without implementing the area function, but this doesn&#8217;t mean we must create a class (as such), we can create what C# might call and anonymous type, for example<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nval s = new Shape {\r\n   override def area: Int = 20\r\n}\r\n<\/pre>\n<p>But ofcourse, we can also extend the trait with another trait or a concrete implementation as a class, for example<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nclass Rectangle(width: Int, height: Int) extends Shape {\r\n  def area = width * height\r\n}\r\n<\/pre>\n<p>Functions, by default, are virtual (as per Java) and so we can override the <em>name<\/em> function, for example<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nclass Rectangle(width: Int, height: Int) extends Shape{\r\n  def area = width * height\r\n\r\n  override def name: String = &quot;Rectangle&quot;\r\n}\r\n<\/pre>\n<p>If we want to stop a function being overridden we can use the final keyword (again like java). So Shape might be defined as <\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\ntrait Shape {\r\n  def area : Int\r\n\r\n  final def name = &quot;Shape&quot;\r\n}\r\n<\/pre>\n<p><strong>Trait as an interface<\/strong><\/p>\n<p>So one thing you might notice is that in C# and Java we have the concept of an interface. Scala doesn&#8217;t support a specific interface keyword. So in this way it&#8217;s similar to C++ in that we can simply use a trait without any implementations.<\/p>\n<p>For example<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\ntrait Shape {\r\n   def area : Int\r\n}\r\n<\/pre>\n<p>We can extend traits, for example<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\ntrait Triangle extends Shape {\r\n  def isRightAngle : Boolean\r\n}\r\n<\/pre>\n<p>and ofcourse we could have implemented some functions within the extended type. To implement a class from a Triangle we can just write the following<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nclass RightAngleTriangle(adjacent: Int, opposite: Int) extends Triangle {\r\n  override def area: Int = (adjacent * opposite) \/ 2\r\n  override def isRightAngle: Boolean = true\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Recap on what a class, object and trait are&#8230; A class is analogous to a C# class which is created on a per instance bases. An object is a singleton, analogous to a static class in C# and a trait can how declarations of functions (without implementations) or include implementations which is analogous to 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":[165],"tags":[],"class_list":["post-4749","post","type-post","status-publish","format-standard","hentry","category-scala"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4749","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=4749"}],"version-history":[{"count":11,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4749\/revisions"}],"predecessor-version":[{"id":4785,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4749\/revisions\/4785"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=4749"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=4749"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=4749"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}