Scala Foundation Course - Scala Classes


Welcome back. In this video, I am going to talk about Scala classes.
Let's start with the most simple form of a Scala class. A Scala class definition looks like this.

                                
    class Circle { }                                          
                            

You start with the keyword class. Give a name to the class and place the body of the class in a pair of curly braces. You can create abstract, private or protected classes by using appropriate keywords. But you can't use a public access modifier. That's not allowed. A Scala class is public by default. So, if you want to create a public class, don't use any other access modifier. It becomes public by default. There is one more important point that you should note here.

  1. Unlike Java, a Scala source file can contain multiple public classes. If you programmed in Java, you already know what it means. A Java source file can have only one public class. But that restriction is no more valid in Scala.
  2. You can define multiple public classes in a single source file and name the source file whatever you want. There is no need to match the file name with the public class name.

Let's come back to the class definition. Like any other object-oriented language, you can add fields and methods to a Class.

                                
    class Circle { 
        var radius = 0
        def draw = { println("Drawing the circle of radius " + radius) }
    }                                               
                            

The field radius and the methods draw are public because we don't specify an access modifier. You must initialize the radius with some value because you cannot define a variable in Scala with no value.
Class methods are like Scala functions. The only difference is that you define them as part of the class definitions and they become a member of a class. Otherwise, everything that you learned about Scala functions is also applicable to methods.
So far so good. Now, it’s time to look at Scala specific behaviour. When you define a var field in a Scala class, the compiler generates two methods.

  • Reader
  • Writer

If you want to see them, create a class as shown in the above example. Instantiate it as shown below. Type c. and press tab.

                                
    val c = new Circle
        /*Output
            radius     radius_=
        */                                          
                            

You will see two methods. The first one is the reader and the second one is the writer. In the previous lesson, I talked about the Java getter and a setter method. The first method radius is your getter and the second method radius_= is your setter. You don't need to define them. You get it free. Scala compiler automatically generates them.
You can call the reader and the writer method as shown below.

                                
    c.radius
    c.radius_=(5)
    //But no one calls the writer using this notation. We can simply call it like this.
    c.radius=5                                          
                            

Those automatically generated readers and writers will save you from creating default getter and setter methods. In the previous lession, I also talked about the need to add some validations to these methods. For example, you don't want people to set the radius to a negative number. In fact, you want to add validation to the writer method.
How will you do that? Scala compiler is automatically generating them. You don't have control over those methods.
Well, you must go back to the java style. Create a private variable to hold the radius. Then, implement your custom reader and writer methods. That's how we do it in Java. Right? Let's look at the code.

                                
    class Circle { 
        private varp_radius = 0
        //TODO: implement reader/writer methods
    }                                           
                            

Now, we create a private var for the radius. Earlier we created a default public var. In that case, Scala generates two public methods for the radius, the reader and the writer. Now, we have a private var, and Scala will still generate the reader and writer methods. But now, those methods will be private because we made the radius private.
Great! Now, we are ready to write a custom reader and the writer. The code for the reader is extremely simple. Start with def, give a method name, place an equal-to symbol to start the body, and then write the body. We don't have much to be done. Just return the private variable. That's it.

                                
    class Circle { 
        private varp_radius = 0
        //Reader
        def radius = p_radius
    }                                               
                            

The code for the writer is also simple. Start with def and give a method name. The writer name follows a special notation. I will come back to the notation. But for now, let's move on. Since it is writer method, we need to take the new radius as input. Place an equal-to symbol to start the body, and then write the body. Now you can implement the validation. If the new radius is invalid, throw an exception else set the private variable. That's it.

                                
    class Circle { 
        private varp_radius = 0
        //Reader
        def radius = p_radius
        //Writer
        def radius_=(r:Int) = {
            if(r < 0) throw new Exception("-ive not allowed") else p_radius=r
        }  
        def setRadius(r:Int) = {
            if(r < 0) throw new Exception("-ive not allowed") else p_radius=r
        }
    }
    val c = new Circle                                              
                            

Great, let's come back to the special naming of the writer method. The name of the writer method follows a particular syntax. A string, then an underscore and finally an equal to symbol. If you are creating a writer method, you must follow this naming convention. To demonstrate the benefit of following that naming convention, I have also added another method setRadius. The writer method radius and the normal method setRadius are functionally same. They do the same thing. The only difference is in their naming convention.
If you compile the class and create an object. Type c. and press the tab. You can see the reader and writer like earlier. The p_radius is private, but we implemented our custom reader and writer. Those two methods will allow us to read and write the radius like earlier. If you try to set the radius to a negative value, you will see an exception.
The important point to note is that you can start with the public fields in your class definition. After few months, when you realized that you need to add some validations to the public fields, you can modify the class definition to use a private field and convert the public fields to a pair of custom methods. In all this, the downstream code never realized that you changed the public field to a public method.
Great. Now the special naming convention for the writer method. We used the radius method to set the radius of the circle. You can try to do the same thing using the setRadius method as shown below.

                                
    c.setRadius = 5                                               
                            

You should get an error. You can't use the setRadius with an equal to operator. But we were able to use the radius method for the same thing. Right? That's because the radius method is using a special naming convention. That naming convention is an instruction to the compiler to allow an equal-to operator on that method. If you want to use the setRadius method, you can use it as a standard method call, but you can't use it with an equal-to operator.

                                
    c.setRadius(5)                                               
                            

Great. So, the takeaway from this example is that, when you need the default reader and writer, use a public field. When you need custom reader and writer, use a private field and implement your custom reader and writer methods.
Now, one last thing. A simple quiz. Just look at the below code.

                                
    class Circle { 
        val radius = 0
    }                                           
                            

I changed the type of the radius to a val. Earlier, it was a var. You already learned that when you create a public var, Scala will create a public reader and a public writer. When you create a private var, Scala will create a private reader and a private writer. Now the question is this.
Will Scala create a reader and writer for the above example?
We changed the var to a val. And you know that the val is a constant. You can't change it. So, Scala will not create a writer for that example. There is no point doing that. It will only create a reader. In above code, val radius is public. And hence, you will get a public reader.
Let me ask you a simple question. When I need a reader and writer both, I create a var field. When I need a reader only and don't want the writer, I create val field. What if I don't need any one of those. Neither a reader nor a writer. How to do that?
Well, the answer is simple. Use a private val and do not implement public methods to access it. Great. That's all about fields and methods in a Scala class. In the next lession, I will talk about constructors in a Scala class.


You will also like:


Scala Functions

Scala is a functional programming language. Functions are the building blocks in Scala.

Learning Journal

First Class Functions

Function is a first-class citizen in functional programming. What does it mean?

Learning Journal

Hadoop Security

Hadoop security implementation using Kerberos.

Learning Journal

Scala placeholder syntax

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

Learning Journal

Spark in Google cloud

Learn How to Install Hadoop and Spark in Google Cloud in just 2 minuts.

Learning Journal