橘子味的心
标题:Java多态

Java中的多态是一个概念,通过它我们可以通过不同的方式执行单个动作(方法)。 多态性派生自2个希腊词:“poly”和“morphs”。 词语“poly”意为许多,“morphs”意为形式。 所以多态表示为多种形式。

在Java中有两种类型的多态性:编译时多态性和运行时多态性。 我们可以通过方法重载和方法覆盖在java中执行多态性。

如果在Java中重载静态方法,它就是编译时多态性的例子。 这里,我们将关注Java中的运行时多态性。

1. Java运行时多态性

运行时多态性或动态方法分派是一个过程,它对重写方法的调用在运行时体现而不是编译时。

在此过程中,通过超类的引用变量调用重写的方法。 要调用的方法基于引用的对象。

了解运行时多态性之前,让我们先来向上转换。

向上转换

当父类的引用变量引用子类的对象时,称为向上转换。 例如:

  1. class A{}
  2. class B extends A{}
  3. A a=new B(); //向上转换...
  4. Java

Java运行时多态性示例1

在这个例子中,我们创建两个类:BikeSplendarSplendar类扩展Bike类并覆盖其run()方法。通过父类(Bike)的引用变量调用run方法。 因为它引用子类对象,并且子类方法覆盖父类方法,子类方法在运行时被调用。

  1. 因为方法调用是由JVM不是编译器决定的,所以它被称为运行时多态性。
  2. Java
  1. class Bike {
  2. void run() {
  3. System.out.println("running");
  4. }
  5. }
  6.  
  7. class Splender extends Bike {
  8. void run() {
  9. System.out.println("running safely with 60km");
  10. }
  11.  
  12. public static void main(String args[]) {
  13. Bike b = new Splender();// upcasting - 向上转换
  14. b.run();
  15. }
  16. }
  17. Java

执行上面代码得到以下结果 -

  1. running safely with 60km.
  2. Java

Java运行时多态性示例2:Bank

考虑一种情况,Bank类是一个提供获得利率的方法的类。 但是,利率可能因银行而异。 例如,SBIICICIAXIS银行分别提供8.4%7.3%9.7%的利率。

注意:此示例也在方法覆盖中给出,但没有向上转换。

  1. class Bank {
  2. float getRateOfInterest() {
  3. return 0;
  4. }
  5. }
  6.  
  7. class SBI extends Bank {
  8. float getRateOfInterest() {
  9. return 8.4f;
  10. }
  11. }
  12.  
  13. class ICICI extends Bank {
  14. float getRateOfInterest() {
  15. return 7.3f;
  16. }
  17. }
  18.  
  19. class AXIS extends Bank {
  20. float getRateOfInterest() {
  21. return 9.7f;
  22. }
  23. }
  24.  
  25. class TestPolymorphism {
  26. public static void main(String args[]) {
  27. Bank b;
  28. b = new SBI();
  29. System.out.println("SBI Rate of Interest: " + b.getRateOfInterest());
  30. b = new ICICI();
  31. System.out.println("ICICI Rate of Interest: " + b.getRateOfInterest());
  32. b = new AXIS();
  33. System.out.println("AXIS Rate of Interest: " + b.getRateOfInterest());
  34. }
  35. }
  36. Java

上面代码执行结果如下 -

  1. SBI Rate of Interest: 8.4
  2. ICICI Rate of Interest: 7.3
  3. AXIS Rate of Interest: 9.7
  4. Java

Java运行时多态性示例3:Shape

  1. class Shape { // 基类(形状)
  2. void draw() {
  3. System.out.println("drawing...");
  4. }
  5. }
  6.  
  7. class Rectangle extends Shape {
  8. void draw() {
  9. System.out.println("drawing rectangle...");
  10. }
  11. }
  12.  
  13. class Circle extends Shape {
  14. void draw() {
  15. System.out.println("drawing circle...");
  16. }
  17. }
  18.  
  19. class Triangle extends Shape {
  20. void draw() {
  21. System.out.println("drawing triangle...");
  22. }
  23. }
  24.  
  25. class TestPolymorphism2 {
  26. public static void main(String args[]) {
  27. Shape s;
  28. s = new Rectangle();
  29. s.draw();
  30. s = new Circle();
  31. s.draw();
  32. s = new Triangle();
  33. s.draw();
  34. }
  35. }
  36. Java

上面代码执行结果如下 -

  1. drawing rectangle...
  2. drawing circle...
  3. drawing triangle...
  4. Java

Java运行时多态性示例4:Animal

  1. class Animal {
  2. void eat() {
  3. System.out.println("eating...");
  4. }
  5. }
  6.  
  7. class Dog extends Animal {
  8. void eat() {
  9. System.out.println("eating bread...");
  10. }
  11. }
  12.  
  13. class Cat extends Animal {
  14. void eat() {
  15. System.out.println("eating rat...");
  16. }
  17. }
  18.  
  19. class Lion extends Animal {
  20. void eat() {
  21. System.out.println("eating meat...");
  22. }
  23. }
  24.  
  25. class TestPolymorphism3 {
  26. public static void main(String[] args) {
  27. Animal a;
  28. a = new Dog();
  29. a.eat();
  30. a = new Cat();
  31. a.eat();
  32. a = new Lion();
  33. a.eat();
  34. }
  35. }
  36. Java

上面代码执行结果如下 -

  1. eating bread...
  2. eating rat...
  3. eating meat...
  4. Java

Java运行时多态性与数据成员

上面示例中,都是有关方法被覆盖而不是数据成员,因此运行时多态性不能由数据成员实现。
在下面给出的例子中,这两个类都有一个数据成员:speedlimit,通过引用子类对象的父类的引用变量来访问数据成员。 由于我们访问的数据成员没有被重写,因此它将访问父类的数据成员。

规则: 运行时多态性不能由数据成员实现。

  1. class Bike {
  2. int speedlimit = 90;
  3. }
  4.  
  5. class Honda3 extends Bike {
  6. int speedlimit = 150;
  7.  
  8. public static void main(String args[]){
  9. Bike obj=new Honda3();
  10. System.out.println(obj.speedlimit);//90
  11. }
  12. }
  13. Java

上面代码执行结果如下 -

Java运行时多态性与多级继承

下面让我们来看看一个带有多级继承的运行时多态性的简单例子。

  1. class Animal {
  2. void eat() {
  3. System.out.println("eating");
  4. }
  5. }
  6.  
  7. class Dog extends Animal {
  8. void eat() {
  9. System.out.println("eating fruits");
  10. }
  11. }
  12.  
  13. class BabyDog extends Dog {
  14. void eat() {
  15. System.out.println("drinking milk");
  16. }
  17.  
  18. public static void main(String args[]) {
  19. Animal a1, a2, a3;
  20. a1 = new Animal();
  21. a2 = new Dog();
  22. a3 = new BabyDog();
  23. a1.eat();
  24. a2.eat();
  25. a3.eat();
  26. }
  27. }
  28. Java

上面代码执行结果如下 -

  1. eating
  2. eating fruits
  3. drinking Milk
  4. Java

尝试下面一段代码的输出:

  1. class Animal {
  2. void eat() {
  3. System.out.println("animal is eating...");
  4. }
  5. }
  6.  
  7. class Dog extends Animal {
  8. void eat() {
  9. System.out.println("dog is eating...");
  10. }
  11. }
  12.  
  13. class BabyDog1 extends Dog {
  14. public static void main(String args[]) {
  15. Animal a = new BabyDog1();
  16. a.eat();
  17. }
  18. }
  19. Java

执行上述代码,结果如下:

  1. Dog is eating
  2. Java

因为,BabyDog不会覆盖eat()方法,所以这里是Dog类的eat()方法被调用。