Polymorphism = Poly == multiple, morph == forms
Types of polymorphism:
- Compile Time Polymorphism or Static Polymorphism, Example: Method Overloading
- Run time polymorphism or Dynamic Polymorphism, Example: Method Overriding
Overloading | Overriding |
|
|
- Overloading: Two methods are said to be overloaded if and only if both methods have same name but different signature (argument types or input). It happens within the same class.
Example:
class Test{
public void m1(int i) {
}
public void m1(long l) {
}
}
II: Example
package com.cerotid.oo.principles;
class Test{
void m1(int a) {
System.out.println("int a m1 method");
}
void m1(int a, int b) {
System.out.println("int a int b m1 method");
}
void m1(char ch) {
System.out.println("char m1 method");
}
}
public class OverloadingDemo {
public static void main(String[] args) {
Test t = new Test();
t.m1(10);
t.m1(10, 20);
t.m1('a');
}
}
Output:
int a m1 method
int a int b m1 method
char m1 method
Overriding: Whatever methods parent has, by default available to the child through inheritance. Some times child may not satisfy with parent method implementation. Then, child is allow to redefine that method with the same method name and parameters but different implementation in the child class . This process is called overriding.
- Methods having same name and same argument in parent class and child class is known as overriding.
- The parent method which is overridden is called overridden method
- The child method which is overriding is called overriding method
- In overloading, same method name but different parameters and in overriding, same method name as well as same parameters
class Human{
//Overridden method
public void eat()
{
System.out.println("Human is eating");
}}class Boy extends Human{
//Overriding method
public void eat(){
System.out.println("Boy is eating");
}
public static void main( String args[]) {
Boy obj = new Boy();
//This will call the child class version of eat()
obj.eat();
}}
Output: Boy is eating
8 Rules in overridden:
While overriding method, overridden method signature and overriding method signature must be same
Example I:
class Vehicle {
void run() {
System.out.println("Vehicle is running");
}
}
class Bike extends Vehicle{
void run(){
System.out.println("Bike is running");
}
}
public class OverridingDemo3 {
public static void main(String[] args) {
Bike bk = new Bike();
bk.run();
}
}
Output:
Bike is running
Example II:
class Animal1{
public void whoAmI() {// overridden method signature
System.out.println("I am an Animal1");
}
}
class Horse extends Animal1{
public void whoAmI() { //overriding method signature
System.out.println("I am a horse");
}
}
public class OverridingDemo {
public static void main(String[] args) {
Animal1 a = new Animal1(); //Animal1 reference and Animal1 object
Animal1 h = new Horse(); //Animlal1 reference but Horse object
Horse h1 = new Horse(); //Horse reference and Horse object
a.whoAmI(); //runs the method in Animal1 class
h.whoAmI(); //runs the method in Horse class
h1.whoAmI(); // runs method in Horse class
}
}
Output:
I am an Animal1
I am a horse
I am a horse
Example III:
class Company{
void address() {
System.out.println("Company address");
}
}
class Amazon extends Company{
void address() {
//super.address();//invokes the parent class method (i.e. represents parent class method)
System.out.println("Amazon address");
}
}
public class OverridingDemo2 {
public static void main(String[] args) {
Company a = new Company(); // parent class reference variable and parent object
Company b = new Amazon(); //parent class reference variable and child object
Amazon c = new Amazon(); //child class reference variable and child object
a.address(); // gives company address only
b.address(); // gives Amazon address only
c.address(); //gives Amazon address only
}
}
Output:
Company address
Amazon address
Amazon address
While overriding method, overridden method return type and overriding method return type must be the same at primitive level
Example I:
class Vehicle {
int run() { // method vs returning primitives
System.out.println("Vehicle is running");
return 70;
}
}
class Bike extends Vehicle{
int run(){
System.out.println("Bike is running");
return 90;
}
}
public class OverridingDemo3 {
public static void main(String[] args) {
Bike bk = new Bike();
bk.run();
}
}
Output: bike is running
It is possible to change the method return type at class level by using co-variant return type
class Animal{}
class Dog extends Animal{}
class Parent{
Animal marry(){
System.out.println("marry a black girl");
Animal a = new Animal();
return a;
//return new Animal();
}
}
class Child extends Parent{
Dog marry(){ //return type, Dog is child class of Animal
System.out.println("marry a red girl");
return new Dog();
}
}
public class CovarientReturnTypeDemo {
public static void main(String[] args) {
new Child().marry();
}
}
Output:
marry a red girl
- It is not possible to override the final method
- Static methods are bonds with class and it is not possible to override the static method. This is called method hiding concept.
- Instance methods are bond with object and it is possible to override the instance methods
- Private methods are specific to class and not visible to outside class . It is not possible to override the private method
- While overriding, it is possible to maintain same level or increase the permission but not possible to reduce the permission
Advantage of method overriding
The main advantage of method overriding is that the class can give its own specific implementation to a inherited method without even modifying the parent class code.
This is helpful when a class has several child classes, so if a child class needs to use the parent class method, it can use it and the other classes that want to have different implementation can use overriding feature to make changes without touching the parent class code.
Example I:
package com.cerotid.oo.principles;
class Vehicle {
void run() {
System.out.println("Vehicle is running");
}
}
class Bike extends Vehicle{
void run(){
System.out.println("Bike is running");
}
}
public class OverridingDemo3 {
public static void main(String[] args) {
Bike bk = new Bike();
bk.run(); // this calls the method present in child class
}
}
Example II:
class Animal1{
public void whoAmI() {
System.out.println("I am an Animal1");
}
}
class Horse extends Animal1{
public void whoAmI() {
System.out.println("I am a horse");
}
}
public class OverridingDemo {
public static void main(String[] args) {
Animal1 a = new Animal1();//Animal1 reference and object
Animal1 h = new Horse();//Animlal1 reference but Horse object
a.whoAmI();//runs the method in Animal1 class
h.whoAmI();//runs the method in Horse class
}
}
Example III:
package com.cerotid.oo.principles;
class Parent{}
class Child extends Parent{}
public class OverridingDemo3 {
public static void main(String[] args) {
Parent p1 = new Parent(); //valid
Parent p2 = new Child(); //valid
Child c1 = new Child(); //valid
//Child c2 = new Parent(); //not valid
//parent class reference variable is able to hold child class object but child class reference variable is not able to hold parent class object
}
}
Example IV:
class Parent{
void m1() {
System.out.println("parent m1()");//overridden method
}
}
class Child extends Parent{
void m1() {
System.out.println("child m1()");//overriding method
}
void m2() {
System.out.println("child m2()");
}
}
class OverridingDemo4{
public static void main(String[] args) {
Parent p = new Child();
p.m1();
// p.m2() // not possible
//when you type cast from parent reference variable to child class object and it is possible to call m2() method
Child c = (Child) p;
c.m2();
}
}
Output:
child m1()
child m2()
Note:I When I am calling p.m1(), at compile time, compiler is checking method in parent class, method is available and it is executed. At run time, child class object is created in the child class and child class method is executed.
II: when I am calling p.m2(), compile time compiler is checking method in parent class, method is not available and error message. Then we have to type cast parent class reference variable p to child class object and now we can call m2() without having error.
Example VI: Parent class reference variable and child class object
package com.cerotid.oo.principles;
interface WebDriver{
void get();// abstract method (ending with semicolon)
void window();
}
class FirefoxDriver implements WebDriver{
public void get() { } //overriding method
public void window() { } //overriding method
void x() { } //direct method
void y() { } //direct method
}
public class OverridingDemo5 {
public static void main(String[] args) {
Parent p = new Child();// concept
WebDriver driver = new FirefoxDriver();
driver.get();// compile time: WebDriver runtime: FirefoxDriver
driver.window();//compile time: WebDriver runtime: FirefoxDriver
//driver.x(); //compile time : WebDriver runtime: compilation error
Need to type cast from (Parent class reference variable) driver to (Child class object) FirefoxDriver.
FirefoxDriver f = (FirefoxDriver)driver;
f.x();
f.y();
}
}
Example VI: it is not possible to override the static methods in java because static methods are bonds with class
class Parent{
static void m1() {
System.out.println("parent m1()");//overridden method
}
}
class Child extends Parent{
static void m1() {
System.out.println("child m1()");//overriding method
}
}
class OverridingDemo4{
public static void main(String[] args) {
Parent p = new Child();
p.m1();
// p.m2() // not possible
//when you type cast from parent reference variable to child class object and it is possible to call m2() method
}
}
Output: parent m1() because static methods are specific to class
No comments:
Post a Comment