Scala Foundation Course - Object Oriented Scala Introduction


Welcome back. In this section, I will talk about the Object Oriented features of Scala. I am assuming that you are already familiar with Object Oriented concepts. If you had an opportunity to learn C++ or Java or may be any other object-oriented language, you are good to start this section. I am assuming that you are already familiar with Object Oriented concepts and in this section, we will discuss Scala implementation of those concepts.
In the next set of videos, we will cover following topics.

  1. Classes
  2. Objects
  3. Inheritance
  4. Traits
  5. Packages

Before we start learning Object Oriented Scala, let me introduce you to the Scala's concise coding style. We will start with a simple example. The code shown below is a typical Class definition.

                                
    class JCustomer{
        //Private properties
        private var custID:Int = 0
        private var custName:String = null
        
        //Public constructor
        def this(id:Int, name:String) {
            this()
            this.custID = id   
            this.custName = name
        }
        
        //Public getter 
        def getID() = custID
        def getName() = custName
        
        //Public setter  
        def setID(nID:Int) =  custID = nID
        def setName(nName:String) =  custName = nName
    }                                           
                            

The above code is a Java style class definition, but I wrote it in Scala. In Java style, you will have some private properties and a public constructor. You will also have a getter and a setter for your private properties. When you want to instantiate and use this class, you will write code like this.

                                
    val c = new JCustomer(101,"XYZ Corp")
    //When you want to read the private field, you will call a getter method.
    c.getID()
    //When you want to modify the private field, you will call a setter method. 
    c.setName("XYZ Corporation")
    c.getName()                                             
                            

These are the basic things in Java programming. Everyone knows it. You might be wondering, why I am talking about these things. Is there anything wrong with this code or style? No. Everything is good. Scala as a language supports that style, but that's not Scala style. Let's see how we can do the same thing in Scala. Here is the class definition.

                                
    class Customer(var id:Int, var name:String)                                          
                            

Scala is concise

That one-liner replaces all the code that we wrote earlier. You can instantiate the class as you do it in Java.

                                
    val c = new Customer(101,"XYZ Corp")
    //But when you want to read the members variables, instead of calling a getter method, you will use them directly.
    c.id
    c.name
    //There is no need to call a getID and getName methods. 
    //You don't even need the set methods as well. You can directly modify the members.
    c.id = 101
    c.name = "XYZ Corp"                                       
                            

If you are a Java programmer, you might argue that this whole thing is not a big deal. We can do that in Java as well. I mean, the single line class definition is impressive, but those members appear to be a public field. If we declare our members using a public modifier, we can achieve the same thing in Java. But In object-oriented languages, we don't prefer using public fields. We prefer using a private field and a get/set method. Do you agree with this argument?
If yes, let me ask you a question. What is wrong with a public field? Why do you want to use a get and a set method pair?
In fact, that's an easy question. When we use a method, we can add logic to validate the data.
Let me show you a Java-style example.

                                
    class JCircle{
        //Private field
        private var radius = 0
        //Constructor
        def this(r:Int) {
            this()
            setRadius(r)
        }
        //Set method with data validation
        def setRadius(r:Int):Unit =  {
            if(r < 0) throw new Exception("-ive not allowed") else radius=r
        }
        //Get method
        def getRadius() = radius
    }                                       
                            

The above code defines a Class for a circle. We want to make sure that no one should be able to set the radius of a circle to a negative number. So, we make the radius private and implement a setRadius method. Once you have a method, you can add the logic to validate the radius. That's the main reasoning behind making our members private and implementing a get/set method pair. That's a good reason. But you must agree that using a public field is more convenient compared to using a method call for four reasons.

  1. You are typing less.
  2. Your code is easy to read.
  3. It looks more like a mathematical expression.
  4. You are following the functional programming principal. I mean, the functions and values should work in the same way.

When you use c.radius, you are using it as a value without knowing whether it is a value or a function. In fact, to your surprise, the radius in the above example is internally a function.

Scala is flexible

Since the radius in the above example is internally a function, we are not losing the ability to add some logic. I can still add logic to validate the data. Here is a code for Scala circle.

                                
    class Circle{
        //Private field
        private var _pradius = 0
        //Constructor
        def this(r:Int) {
            this()
            radius=r
        }
        //Set method with data validation
        def radius_=(r:Int) = {
            if(r < 0) throw new Exception("-ive not allowed") else _pradius=r
        }
        //Get method
        def radius  = _pradius
    }                                       
                            

Don't worry if you don't understand the code. I will explain everything in the upcoming sections. But these examples demonstrate following.

  1. When you don't need to implement the validation, you can use a concise code (a single liner class definition).
  2. When you need to add validation, you can modify your code and put validation in place
  3. Adding a validation is not going to impact the rest of the code. You can still use the members as a public field.

If you didn't get it very well, don't worry. I will come back to above example again in the next lesson. But, the point that I wanted to make is very simple and straightforward. When you are learning Scala's Object-Oriented features and syntaxes, learn it with an open mind. When you are coding in Scala, bring your mind out of the Java Style and use Scala 's approach. You will find it sweet and short.
In the next video, I will formally start object-oriented Scala and talk about Scala Classes.



You will also like:


Kafka Core Concepts

Learn Apache Kafka core concepts and build a solid foundation on Apache Kafka.

Learning Journal

Pattern Matching

Scala takes the credit to bring pattern matching to the center.

Learning Journal

Apache Spark Introduction

What is Apache Spark and how it works? Learn Spark Architecture.

Learning Journal

Scala placeholder syntax

What is a scala placeholder syntax and why do we need it? Learn from experts.

Learning Journal

Higher Order functions

Scala allows you to create Higher Order functions as first class citizens.

Learning Journal