Saturday, 18 May 2019

Closures functions in Scala


Closures functions
Scala Closures are functions which uses one or more free variables and the return value of this function is dependent of these variable. The free variables are defined outside of the Closure Function and is not included as a parameter of this function. So the difference between a closure function and a normal function is the free variable. A free variable is any kind of variable which is not defined within the function and not passed as the parameter of the function. A free variable is not bound to a function with a valid value. The function does not contain any values for the free variable.
A closure function can further be classified into pure and impure functions, depending on the type of the free variable. If we give the free variable a type var then the variable tends to change the value any time throughout the entire code and thus may result in changing the value of the closure function. Thus this closure is a impure function. On the other-hand if we declare the free variable of the type val then the value of the variable remains constant and thus making the closure function a pure one.
Example:
object UVPM
{
    // Main method
    def main(args: Array[String])
    {
        println( "Final_Sum of first value = " + sum(1))
        println( "Final_Sum of second value = " + sum(2))
        println( "Final_Sum of third value = " + sum(3))
    }       
    var a = 44
    // define closure function
    val sum = (b:Int) => b + a
}
//Output:
Final_Sum of first value = 5
Final_Sum of second value = 6
Final_Sum of third value = 7
Here, In above program function sum is a closure function. var a = 4 is impure closure. the value of a is same and values of b is different.

Polymorphism in Scala


Polymorphism
Polymorphism is an object-oriented programming concept that refers to the ability of a variable, function or object to take on multiple forms.
Method Overloading in Scala
Method Overloading is the common way of implementing polymorphism. It is the ability to redefine a function in more than one form. A user can implement function overloading by defining two or more functions in a class sharing the same name. Scala can distinguish the methods with different method signatures within the same class.
Overloaded methods are differentiated based on the number and type of the parameters passed as an argument to the methods.
We can not define more than one method with the same name, Order and the type of the arguments. It would be a compiler error.
The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and different return type. It will throw a compile-time error.
Why do we need Method Overloading ??
If we need to do the same kind of operation in different ways i.e. for different inputs. In the example described below, we are doing the addition operation for different inputs. It is hard to find many different meaningful names for single action.
Different ways of doing overloading methods
Method overloading can be done by changing:
·                   The number of parameters in two methods.
·                   The data types of the parameters of methods.
·                   The Order of the parameters of methods.
By changing the number of parameters.
class GFG
{
      // function 1 with two parameters
    def fun(p:Int, q:Int)
    {
        var Sum = p + q;
        println("Sum in function 1 is:" + Sum);
    }
    // function 2 with three parameters
    def fun(p:Int, q:Int, r:Int)
    {
        var Sum = p + q + r;
        println("Sum in function 2 is:" + Sum);
    }
}
object Main 
{
    // Main function
    def main(args: Array[String]) 
    {     
    // Creating object of GFG class
    var obj = new GFG();
    obj.fun(6, 8);
    obj.fun(5, 10, 58);
    }
}
//Output
Sum in function 1 is:14
Sum in function 2 is:73

By changing the Data types of the parameters
Example:
class GFG
{  
    // Adding three integer elements
    def fun(p:Int, q:Int, r:Int)
    {
        var Sum = p + q + r;
        println("Sum in function 1 is:"+Sum);
    } 
    // Adding three double elements
    def fun(p:Double, q:Double, r:Double)
    {
        var Sum = p + q + r;
        println("Sum in function 2 is:"+Sum);
    }
}
object Main 
{
    // Main method
    def main(args: Array[String]) 
    {     
    // Creating object of GFG class
    var obj = new GFG();
    obj.fun(6, 8, 10);
    obj.fun(5.9, 10.01, 58.7);
    }
}
//Output:
Sum in function 1 is:24
Sum in function 2 is:74.61

By changing the Order of the parameters
Example:
class GFG
{
    // Function 1
    def fun(name:String, No:Int)
    {
        println("Name of the watch company is:" + name);
        println("Total number of watch :" + No);
    }
   // Function 2
    def fun(No:Int, name:String )
    {
        println("Name of the watch company is:" + name);
        println("Total number of watch :" + No);
    }
}
object Main 
{
    // Main Function
    def main(args: Array[String])
    {
   // Creating object of GFG class
    var obj = new GFG();
    obj.fun("Rolex", 10);
    obj.fun("Omega", 10);
    }
}
Output:
Name of the watch company is:Rolex
Total number of watch :10
Name of the watch company is:Omega
Total number of watch :10

What happens when method signature is same and the return type is different?
The compiler will give error as the return value alone is not sufficient for the compiler to figure out which function it has to call. Only if both methods have different parameter types (so, they have the different signature), then Method overloading is possible.
Example:
object Main {
        // Main method
        def main(args: Array[String]) {
     println("Sum in function 1 is:" + fun(6, 8) );
     println("Sum in function 2 is:" + fun(6, 8) );
    }       
     // function 1 
    def fun(p:Int, q:Int) : Int = {
        var Sum: Int = p + q;
        return Sum;    
    }       
 // function 2 
    def fun(p:Int, q:Int) : Double = {
        var Sum: Double = p + q + 3.7;
        return Sum;
    }
}
Compile-time Error:


Method Overriding in Scala
Method Overriding in Scala is identical to the method overriding in Java but in Scala, the overriding features are further elaborated as here, both methods as well as var or val can be overridden. If a subclass has the method name identical to the method name defined in the parent class then it is known to be Method Overriding
When to apply Method Overriding ?
when a subclass wishes to impart a particular implementation for the method defined in the parent class then that subclass overrides the defined method from the parent class. When we wish to reconstruct the method defined in the super class then we can apply method overriding.
Let’s see an example which is related to the diagram mentioned above of the method overriding.
Example :
class School
{ 
    // Method defined
    def NumberOfStudents()=
    { 
        0 // Utilized for returning an Integer
    } 
} 
 
// Creating a subclass 
class class_1 extends School
{
    // Using Override keyword
    override def NumberOfStudents()=
    { 30 } 
} 
 
// Creating a subclass 
class class_2 extends School
{ 
    // Using override keyword 
    override def NumberOfStudents()=
    { 32 } 
} 
 
// Creating a subclass
class class_3 extends School
{  
    // Using override keyword
    override def NumberOfStudents()=
    { 29 } 
} 
 
// Creating object 
object GfG
{ 
    // Main method
    def main(args:Array[String])
    {   
        // Creating instances of all
        // the sub-classes
        var x=new class_1() 
        var y=new class_2() 
        var z=new class_3() 
        // Displays number of students in class_1
        println("Number of students in class 1 : " +  x.NumberOfStudents())  
        // Displays number of students in class_2
        println("Number of students in class 2 : " +  y.NumberOfStudents()) 
        // Displays number of students in class_3
        println("Number of students in class 3 : " + z.NumberOfStudents())  
    } 
} 
Output:
Number of students in class 1 : 30
Number of students in class 2 : 32
Number of students in class 3 : 29

Other Example:
class Shapes
{ 
    // Method defined with parameters
    def Area(l:Double, b:Double, r:Double)=
    { 
                        0.0 // Utilized for returning double
    } 
}   
// Creating a subclass 
class Rectangle extends Shapes
{
    // Overriding method to find area of the rectangle 
    override def Area(l:Double, b:Double, r:Double)=
    { 
      (l * b)
    } 
} 
// Creating a subclass 
class Circle extends Shapes
{ 
    // Overriding method to find area of the circle
    override def Area(l:Double, b:Double, r:Double)=
    {  
        ((3.14)* r * r)
    } 
} 
// Creating object 
object GfG
{ 
    // Main method
    def main(args:Array[String])
    {   
        // Creating instances of all the sub-classes
        var rectangle = new Rectangle() 
        var circle = new Circle()  
        // Displays area of the rectangle
        println(rectangle.Area(3, 11, 4)) 
        // Displays area of the circle
        println(circle.Area(1, 7, 10)) 
    } 
} 
Output:
33.0
314.0

Rules for Method Overriding
There are a few restrictions that we need to follow for method overriding, these are as follows:
·         For method overriding, one of the crucial rule is that the class which is overriding needs to utilize the modifier override or override annotation.
·         Auxiliary constructors are not able to call the super-class constructors immediately. They can hardly call the primary constructors which in reversal will call the super-class constructor.
·         In Method Overriding, we won’t be able to override a var with a def or val, otherwise it throws an error.
·         Here, we won’t be able to override a val in the super-class by a var or def in the subclass, and if the var in the super-class is abstract then we can override it in the subclass.
·         If a field is stated var then it can override the def which is defined in the super-class. The var can only override a getter or setter combination in the super-class.
Note:
1.     Auxiliary Constructors are defined like methods utilizing def and this keywords, where this is the name of the constructor.
2.     Primary Constructors begins from the beginning of the class definition and stretches the whole body of the class.

Overriding vs Overloading
·         In Scala, method overloading supplies us with a property which permits us to define methods of identical name but they have different parameters or data types whereas, method overriding permits us to redefine method body of the super class in the subclass of same name and same parameters or data types in order to alter the performance of the method.
·         In Scala, method overriding uses override modifier in order to override a method defined in the super class whereas, method overloading does not requires any keyword or modifier, we just need to change, the order of the parameters used or the number of the parameters of the method or the data types of the parameters for method overloading.

Use filter method to filter a Scala collection

Use filter method to filter a Scala collection To use filter on your collection, give it a predicate to filter the collection elements as...