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.