Programming in Scala Gist 10

Vinu Charanya
vTechNotes
Published in
7 min readMay 29, 2016

These are the key points from the Programming in Scala, Second Edition by Martin Odersky, Lex Spoon, Bill Venners. I wanted to make note of some key points. They may seem broken and not make much sense, if you have not read the book. This is for personal reference. Feel free to correct me if I have interpreted anything wrong in this post.

Chapter 10— Composition and Inheritance

In this chapter we’ll compare two fundamental relationships between classes: composition and inheritance.

  • Composition means one class holds a reference to another, using the referenced class to help to fulfill its mission.
  • Inheritance is the superclass/subclass relationship.

10.1 A two-dimensional layout library

A running example to create a library for building and rendering two-dimensional layout elements. Elements are rectangles filed with text. Type: Element. It has two composing operators often called combinators (combine elements of some domain into new elements). Combinators is a good way to approach library designs — fundamental ways to construct objects in an application domain.

Two dimensional layout library

10.2 Abstract classes

  • First task is to create a type Element for the layout elements. contents is a member of type Element which is an array of string where each string represents a line.
  • contents is an abstract member of the class Element, that is declared but not defined. Hence, contents is not a concrete method. (Methods that have an implementation are called concrete)
  • The abstract modifier added to the class signifies that the class may have abstract members that do not have an implementation. An abstract method need not carry an abstract modifier as in Java.
Listing 10.1 Defining an abstract method and class

10.3 Defining parameterless methods

  • Methods width and height are parameterless methods (defined without ()). On the contrary, method with empty () are called empty-paren methods.
  • Parameterless method are the recommended convention as it does not change mutable state and supports uniform access principle (client code should not be affected by a decision to implement an attribute as a field or a method)
Uniform access principle
  • Field access vs method invocation — * Field accesses are faster than method call because the values are pre-computed on the class initialization instead on method call. * However, field access requires extra memory space in each object.
  • In Scala, mixing parameterless and empty-paren methods and even overriding a parameterless method with an empty-paren method and vice versa are permitted.
  • To summarize, it is better to call functions with parenthesis (empty-paren) if it has side effects and performs an operations and use parameterless notation, if the function merely provides access to a property.

10.4 Extending classes

  • To create a new elements, lets create an ArrayElement that extends the abstract class Element.
  • Extending a class enables the extending class to inherit all non-private members and makes the extending class a sub-type of the extended class and the extended-class a superclass.
  • Implicitly all classes are sub-class of AnyRef. All members of superclass are members of subclass except private methods and overridden methods.
  • When a non-concrete method is defined in a subclass, it is considered implemented and when a defined concrete class is re-defined in a sub-class it is considered overridden.
  • Subtyping: A value of the subclass can be used wherever a value of the superclass is required.
Subtype in detail …
Abstract class, extends and subtyping
  • Composition relationship exists between ArrayElement and Array[String] because ArrayElement is “composed” out of Array[String] as the Scala compiler will place in to the binary class it generates for ArrayElement a field that holds a reference to the passed “conts” array.

10.5 Overriding methods and fields

  • Scala treats fields and methods more uniformly than Java.
  • Fields and methods belong to the same namespace in Scala and hence a parameterless method can be overridden with a field in Scala.
  • However, Java lets a class have a method and field with the same name which is not permitted in Scala.
  • Java has four namespaces: fields, methods, types and packages
  • Scala has two namespaces: values( fields, methods, packages, and singleton objects) and types (class and trait names)

10.6 Defining parametric fields

  • In the previous ArrayElement example, conts was used merely to copy the variable into the field and avoid name clash. To avoid such code smell, we can use parametric field (A field defined as a class parameter)
  • Prefixing the class parameter with a val is the shorthand that defines a parameter and field at the same time with the same name.
  • The parametric field can be prefixed by var as well to make it reassignable and can also have modifiers such as private, protected or override.
Example of parametric field

10.7 Invoking superclass constructors

  • To invoke a superclass constructor the arguments of the superclass are placed in the parenthesis following the extends SuperclassName as shown above

10.8 Using override modifiers

  • Concrete methods can be overridden in subclass with the modifier “override” which is required.
  • Accidental overrides are the most common manifestation of “fragile base class” problem. Adding new members to base classes in a class hierarchy can cause the risk of breaking the client code.

10.9 Polymorphism and dynamic binding

  • Types of polymorphism: subtyping polymorphism, universal polymorphism.
Uniform Element is a subtype of Element
Subtype Polymorphism: A type of UniformElement/Array Element assigned to Element
  • Method invocations on variables and expressions are dynamically bound (Actual method implementation invoked is determined at run time based on the class of the object, not the type of the variable or expression.
  • Eg., Consider you have a concrete method called demo in Element which are overridden in the subclass A but not in B, passing the superclass as the parameter and invoking demo will call the overridden demo when A is passed as e and the demo from the superclass when B is passed
Dynamic Bound invocation on variables and expressions

10.10 Declaring final members

  • To ensure members cannot be overridden by subclass, a final modifier is added to the member.
  • To ensure an entire class not be classed, declare the entire class final.
Declaring a final method
Declaring a final class

10.11 Using composition and inheritance

  • Composition and inheritance are two ways to define a new class in terms of another existing class.
  • Composition is preferred for code reuse over inheritance. Inheritance models is-a relationship.
  • If LineElement is also made a subclass of Element it has a composition relationship with Array as it holds a reference to an array of strings from its own contents field.
  • Composition relationship is represented in class diagrams by a diamond.

10.12 Implementing above, beside and toString

  • Defining above means concatenating the two contents values of the elements
  • Beside: To put two elements beside each other, we’ll create a new element in which every line results from concatenating corresponding lines of the two elements.
More functional way of implementing beside

10.13 Defining a factory object

  • A factory object contains methods that construct other objects. An advantage of this approach is that object creation can be centralized and the details of how objects are represented with classes can be hidden.
  • The above example uses Companion object to create a factory object.
  • To make classes private they can be placed within the Singleton Object / Companion object and declare them private

10.14 Heighten and Widen, Putting it all together

  • Some missing cases needs to be handled such as placing elements of different widths on top of each other.

Conclusion

In this gist after 10.10 all the concepts in the book are explaining how to go about implementing the problem stated in 10.1. Apart from that, we learnt concepts related object-oriented programming in Scala, abstract classes, inheritance and subtyping, class hierarchies, parametric fields and method overriding.

Previous:

Next:

--

--