📅  最后修改于: 2020-09-25 08:22:03             🧑  作者: Mango
Java中的多态是一个概念,通过它我们可以以不同的方式执行单个操作。多态性源自两个希腊词:poly和morphs。单词“poly”表示很多,“morphs”表示形式。因此,多态性意味着多种形式。
Java中有两种类型的多态:编译时多态和运行时多态。我们可以通过方法重载和方法重写在Java中执行多态。
如果重载Java中的静态方法,则它是编译时多态性的示例。在这里,我们将重点介绍Java中的运行时多态性。
运行时多态性或动态方法调度是一个在运行时而不是编译时解析对覆盖方法的调用的过程。
在此过程中,将通过超类的引用变量调用重写的方法。确定要调用的方法是基于参考变量所引用的对象。
首先让我们了解运行时多态之前的转换。
如果父类的引用变量引用了子类的对象,则称为向上转换。例如:
"class A{}
class B extends A{}
"A a=new B();//upcasting
对于向上转换,我们可以使用类类型或接口类型的引用变量。例如:
"interface I{}
class A{}
class B extends A implements I{}
在这里,B类的关系为:
由于Object是Java中所有类的根类,因此我们可以编写BIS-AObject。
在此示例中,我们将创建两个类Bike和Splendor。Splendor类扩展了Bike类并覆盖其run()方法。我们通过Parent类的引用变量来调用run方法。因为它引用了子类对象,并且子类方法覆盖了Parent类方法,所以在运行时将调用子类方法。
由于方法调用是由JVM而不是编译器确定的,因此称为运行时多态。
"class Bike{
void run(){System.out.println("running");}
}
class Splendor extends Bike{
void run(){System.out.println("running safely with 60km");}
public static void main(String args[]){
Bike b = new Splendor();//upcasting
b.run();
}
}
输出:
running safely with 60km.
考虑一个场景,其中Bank是提供获取利率的方法的类。但是,利率可能因银行而异。例如,SBI,ICICI和AXIS银行提供的利率分别为8.4%,7.3%和9.7%。
注意:该示例也在方法覆盖中给出,但没有向上转换。
"class Bank{
float getRateOfInterest(){return 0;}
}
class SBI extends Bank{
float getRateOfInterest(){return 8.4f;}
}
class ICICI extends Bank{
float getRateOfInterest(){return 7.3f;}
}
class AXIS extends Bank{
float getRateOfInterest(){return 9.7f;}
}
class TestPolymorphism{
public static void main(String args[]){
Bank b;
b=new SBI();
System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());
b=new ICICI();
System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());
b=new AXIS();
System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());
}
}
输出:
SBI Rate of Interest: 8.4 ICICI Rate of Interest: 7.3 AXIS Rate of Interest: 9.7
"class Shape{
void draw(){System.out.println("drawing...");}
}
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle...");}
}
class Circle extends Shape{
void draw(){System.out.println("drawing circle...");}
}
class Triangle extends Shape{
void draw(){System.out.println("drawing triangle...");}
}
class TestPolymorphism2{
public static void main(String args[]){
Shape s;
s=new Rectangle();
s.draw();
s=new Circle();
s.draw();
s=new Triangle();
s.draw();
}
}
输出:
drawing rectangle... drawing circle... drawing triangle...
"class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void eat(){System.out.println("eating bread...");}
}
class Cat extends Animal{
void eat(){System.out.println("eating rat...");}
}
class Lion extends Animal{
void eat(){System.out.println("eating meat...");}
}
class TestPolymorphism3{
public static void main(String[] args){
Animal a;
a=new Dog();
a.eat();
a=new Cat();
a.eat();
a=new Lion();
a.eat();
}}
输出:
eating bread... eating rat... eating meat...
一个方法而不是数据成员被覆盖,因此数据成员无法实现运行时多态。
在下面给出的示例中,两个类都有一个数据成员速度限制。我们正在通过父类的引用变量访问数据成员,该引用变量引用了子类对象。由于我们正在访问未被覆盖的数据成员,因此它将始终访问Parent类的数据成员。
"class Bike{
int speedlimit=90;
}
class Honda3 extends Bike{
int speedlimit=150;
public static void main(String args[]){
Bike obj=new Honda3();
System.out.println(obj.speedlimit);//90
}
输出:
90
让我们看一下具有多级继承的运行时多态的简单示例。
"class Animal{
void eat(){System.out.println("eating");}
}
class Dog extends Animal{
void eat(){System.out.println("eating fruits");}
}
class BabyDog extends Dog{
void eat(){System.out.println("drinking milk");}
public static void main(String args[]){
Animal a1,a2,a3;
a1=new Animal();
a2=new Dog();
a3=new BabyDog();
a1.eat();
a2.eat();
a3.eat();
}
}
输出:
eating eating fruits drinking Milk
"class Animal{
void eat(){System.out.println("animal is eating...");}
}
class Dog extends Animal{
void eat(){System.out.println("dog is eating...");}
}
class BabyDog1 extends Dog{
public static void main(String args[]){
Animal a=new BabyDog1();
a.eat();
}}
输出:
Dog is eating
由于BabyDog不会重载eat()方法,因此将调用Dog类的eat()方法。