Implementing OO relationships
- "is a" relationship is implemented by inheritance (extends keyword)
- "has a" relationship is implemented by providing the class with member variables.
Overloading and Overriding
- Overloading is an example of polymorphism. (operational / parametric)
- Overriding is an example of runtime polymorphism (inclusive)
- A method can have the same name as another method in the same class, provided it forms either a valid overload or override
method overloading
If a class have multiple methods by same name but different parameters, it is known as Method Overloading.
Advantage of method overloading?
purpose: Method overloading increases the readability of the program.
Different ways to overload the method
There are two ways to overload the method in java
|
- By changing number of arguments
- By changing the data type
By changing number of arguments
- class Calculation{
- void sum(int a,int b){System.out.println(a+b);}
- void sum(int a,int b,int c){System.out.println(a+b+c);}
- public static void main(String args[]){
- Calculation obj=new Calculation();
- obj.sum(10,10,10);
- obj.sum(20,20);
- }
- }
Example of Method Overloading by changing data type of argument
- class Calculation{
- void sum(int a,int b){System.out.println(a+b);}
- void sum(double a,double b){System.out.println(a+b);}
- public static void main(String args[]){
- Calculation obj=new Calculation();
- obj.sum(10.5,10.5);
- obj.sum(20,20);
- }
- }
Can we overload main() method?
Yes, by method overloading. You can have any number of main methods in a class by method overloading. Let's see the simple example:
- class Simple{
- public static void main(int a){
- System.out.println(a);
- }
- public static void main(String args[]){
- System.out.println("main() method invoked");
- main(10);
- }
- }
Advantage of Java Method Overriding
- Method Overriding is used to provide specific implementation of a method that is already provided by its super class.
- Method Overriding is used for Runtime Polymorphism
Rules for Method Overriding
- method must have same name as in the parent class
- method must have same parameter as in the parent class.
- must be IS-A relationship (inheritance).
class Vehicle
{
void run()
{
System.out.println("Vehicle is running");
}
}
class Bike extends Vehicle
{
void run()
{
System.out.println("Bike is running safely");
}
public static void main(String args[])
{
Bike obj = new Bike();
obj.run();
}
}
Output: bike is running safely
Can we override static method?
No, static method cannot be overridden. It can be proved by runtime polymorphism
Why we cannot override static method?
because static method is bound with class whereas instance method is bound with object. Static belongs to class area and instance belongs to heap area.
Can we override java main method?
No, because main is a static method.
it can be overloaded
What is the difference between method Overloading and Method Overriding?
There are three basic differences between the method overloading and method overriding. They are as follows:
Method Overloading
|
Method Overriding
|
1) Method overloading is used to increase the readability of the program.
|
Method overriding is used to provide the specific implementation of the method that is already provided by its super class.
|
2) method overloading is performed within a class.
|
Method overriding occurs in two classes that have IS-A relationship.
|
3) In case of method overloading parameter must be different.
|
In case of method overriding parame
|
Shadowing:
Variables can also be overridden, it's known as shadowing or hiding. But, member variable references are resolved at compile-time. So at the runtime, if the class of the object referred by a parent class reference variable, is in fact a sub-class having a shadowing member variable, only the parent class variable is accessed, since it's already resolved at compile time based on the reference variable type. Only methods are resolved at run-time.
class S1
{
public String s = "S1";
public String getS()
{
return s;
}
}
class S2 extends S1
{
public String s = "S2"; //varaible
public String getS() // method
{
return s;
}
}
public class Shadow
{
public static void main(String s[])
{
S1 s1 = new S1();
S2 s2 = new S2();
System.out.println(s1.s); // prints S1
System.out.println(s1.getS()); // prints S1
System.out.println(s2.s); // prints S2
System.out.println(s2.getS()); // prints S2
s1 = s2;
System.out.println(s1.s); // prints S1, not S2 -
// since variable is resolved at compile time
System.out.println(s1.getS()); // prints S2 -
// since method is resolved at run time
}
}
if overiding getS() is not implemented in sub-class then method returns super-class member variable
If a sub-class method calls explicitly a super class method, the super class method always will access the super-class variable.
Super class methods will not access the shadowing variables declared in subclasses because they don't know about them. (When an object is created, instances of all its super-classes are also created.) But the method accessed will be again subject to dynamic lookup. It is always decided at runtime which implementation is called. (Only static methods are resolved at compile-time)
class S1 {
String s = "S1";
public String getS()
{
return s;
}
void display()
{
System.out.println(s);
}
}
class S2 extends S1
{
String s = "S2";
void display()
{
super.display(); // Prints S1
System.out.println(s); // prints S2
}
}
public class Shadow2
{
String s = "main program";
public static void main(String s[])
{
S2 s2 = new S2();
s2.display(); // Produces an output - S1, S2
S1 s1 = new S1();
System.out.println(s1.getS()); // prints S1
System.out.println(s2.getS()); // prints S1 - since super-class method
// always accesses super-class variable
}
}
Sub-classes can use super keyword to access the shadowed variables in super-classes. This technique allows for accessing only the immediate super-class. super.super is not valid. But casting the 'this' reference to classes up above the hierarchy will do the trick. By this way, variables in super-classes above any level can be accessed from a sub-class, since variables are resolved at compile time, when we cast the 'this' reference to a super-super-class, the compiler binds the super-super-class variable. But this technique is not possible with methods since methods are resolved always at runtime, and the method gets called depends on the type of object, not the type of reference variable. So it is not at all possible to access a method in a super-super-class from a subclass.
class GrandParent
{
double wealth = 50000.00;
public double getWealth()
{
System.out.println("GrandParent-" + wealth);
return wealth;
}
}
class Parent extends GrandParent
{
double wealth = 100000.00;
public double getWealth()
{
System.out.println("Parent-" + wealth);
return wealth;
}
}
class Child extends Parent
{
double wealth = 200000.00;
public double getWealth()
{
System.out.println("Child-" + wealth);
return wealth;
}
public void demo() {
getWealth(); // Calls Child method
super.getWealth(); // Calls Parent method
// Compiler error, GrandParent method cannot be accessed
//super.super.getWealth();
// Calls Child method, due to dynamic method lookup
((Parent)this).getWealth();
// Calls Child method, due to dynamic method lookup
((GrandParent)this).getWealth();
System.out.println(wealth); // Prints Child wealth
System.out.println(super.wealth); // Prints Parent wealth
// Prints Parent wealth
System.out.println(((Parent)(this)).wealth);
// Prints GrandParent wealth
System.out.println(((GrandParent)(this)).wealth);
}
}
public class ShadowTest {
public static void main(String s[]){
new STChild().demo();
}
}
Sub-classes can use super keyword to access the shadowed variables in super-classes. This technique allows for accessing only the immediate super-class. super.super is not valid. But casting the 'this' reference to classes up above the hierarchy will do the trick.
variables in super-classes above any level can be accessed from a sub-class, since variables are resolved at compile time, when we cast the 'this' reference to a super-super-class, the compiler binds the super-super-class
So it is not at all possible to access a method in a super-super-class from a subclass.
Advantages
An inherited method, which was not abstract on the super-class, can be declared abstract in a sub-class
Private members are not inherited, but they do exist in the sub-classes. Since the private methods are not inherited, they cannot be overridden.
class Super
{
public void hi()
{ // Super-class implementation always calls superclass hello
hello();
}
private void hello()
{ // This method is not inherited by subclasses, but exists in them.
// Commenting out both the methods in the subclass show this.
// The test will then print "hello-Super" for all three calls
// i.e. Always the super-class implementations are called
System.out.println("hello-Super");
}
}
class Sub extends Super {
public void hi()
{ // This method overrides super-class hi, calls subclass hello
try
{
hello();
}
catch(Exception e) {}
}
void hello() throws Exception
{ // This method is independent from super-class hello
// Evident from, it's allowed to throw Exception
System.out.println("hello-Sub");
}
}
public class PrivateTest {
public static void main(String s[]){
new Super().hi(); // Prints always Super
new Sub().hi(); // Prints Super when subclass doesn't have hi method
// Prints Sub when subclass has hi method
Super sup;
sup = new Sub();
sup.hi(); // Prints Super when subclass doesn't have hi method
// Prints Sub when subclass has hi method
}
}
Can we Override static method ? Explain with reasons ?
No, we cannot override static method. Because static method is bound to class whereas method overriding is associated with object i.e at runtime
No comments:
Post a Comment