Java OOP 中的多态性

多态性是一种 OOP 概念,其中一个名称可以有多种形式。

例如,你用智能手机进行通信。你选择的通信模式可以是任何内容,它可以是通话、短信、图片信息、邮件等。因此,目标通常是沟通,但他们的方法是不同的。这称为多态性。

在本教程中,你将学习 -

  • 什么是多态?
  • OOP 中的 Java 多态与示例
  • 方法覆盖
  • 重载和覆盖之间的区别
  • 什么是动态多态?
  • super 关键字
  • 静态和动态多态性之间的差异

Java 多态与示例

我们有一个父类,Account,具有存款和取款功能。帐户有 2 个子类

存款和取款操作与保存和检查帐户相同。因此,Account 类中的继承方法将起作用。

![Java 继承与多态](/img/Java Inherit Account Example.jpg)

软件要求的变更

软件需求发生了变化,这在软件行业中是非常普遍。你需要添加有透支功能的特权银行账户。

因此,重新实现特权需求的取款方法。但是,你不需要在 SavingChecking 帐户中更改测试过的代码。这是 OOP 的优势。

步骤 1: 这样当调用 Saving 帐户的 withdraw 方法时,执行来自父帐户类的方法。

步骤 2: 但是当特权帐户的 withdraw 方法被调用时,执行特权类中定义的 withdraw 方法。这是多态性。

方法重写

方法重写是在子类中重新定义超类方法。

方法重写规则

  • 方法签名,即方法名称、参数列表和返回类型必须完全匹配。
  • 重写的方法可以扩展可访问性但不会缩小它,即如果它在基类中是私有的,则子类可以使其公开但反之亦然。

例子

class Doctor{
    public void treatPatient(){
        //treatPatient method
}
    
class Surgeon extends Doctor{
    public void treatPatient(){
        //treatPatient method
    }
}
    
Class run{
    public static void main (String args[]){
        Doctor doctorObj = new Doctor();
        //treatPatient method in class Doctor will be executed
        doctorObj.treatPatient();

        Surgeon surgeonObj = new Surgeon();
        //treatPatient  method in class Surgeon  will be executed
        surgeonObj.treatPatient();
    }
}

重载和重写之间的区别

  • **方法重载:**方法重载在同一个类中,其中多个方法具有相同的名称但签名不同。 举例,

    void sum (int a , int b);
    void sum (int a , int b, int c);
    void sum (float a, double b);
    
  • **方法重写:**方法重写是在子类中重新定义超类中的一个方法时。在这种情况下,方法的签名保持不变。

    class X{
        public int sum(){
            // some code
        }
    }
    
    class Y extends X{
        public int sum(){
            //overridden method
            //signature is same
        }
    }
    

什么是动态多态?

动态多态性是一种机制,通过该机制可以在超类和子类中使用相同的名称和签名定义多个方法。在运行时解析对重写方法的调用。

动态多态性示例:

超类的引用变量可以引用子类对象

 Doctor obj = new Surgeon();

比如下面这个语句,

obj.treatPatient();

这里引用变量 obj 是父类,但它指向的对象是子类。

obj.treatPatient() 将执行子类的 treatPatient() 方法 - Surgeon。

如果使用基类引用来调用方法,则要调用的方法由 JVM 决定,具体取决于引用指向的对象。

例如,即使 obj 是对 Doctor 的引用,它也会调用 Surgeon 的方法,因为它指向 Surgeon 对象

这是在运行期间决定的,因此被称为动态运行时多态性

super 关键字

如果 Surgeon 类中的 treatPatient 方法想要执行 Doctor 类中定义的功能然后执行其自己的特定功能,该怎么办?

在这种情况下,关键字 super 可用于从子类访问父类的方法。

Surgeon 类中的 treatPatient 方法可以写成:

treatPatient(){
    super.treatPatient();
    //add code specific to Surgeon
}

关键字 super 可用于访问子类中超类的任何数据成员或方法。 示例: 学习继承、多态和超级关键字

步骤 1: 将以下代码复制到编辑器中

public class Test{
     public static void main(String args[]){
        X x= new X();
       Y y = new  Y();
       y.m2();
      //x.m1();
      //y.m1();
     //x = y;//parent pointing to object of child
     //x.m1() ;
     //y.a=10;
   }
}
class X{
   private int a;
   int b;
      public void m1(){
       System.out.println("This is method m1 of class X");
     }
}
class Y extends X{
      int c; //new instance variable of class Y
         public void m1(){
            //overriden method
            System.out.println("This is method m1 of class Y");
        }
       public void m2(){
           super.m1();
           System.out.println("This is method m2 of class Y");
      }
}

步骤 2: 保存,编译和运行代码。观察输出。

步骤 3: 取消注释行#6-9。保存,编译和运行代码。观察输出。

步骤 4: 取消注释行#10。保存并编译代码。

步骤 5: 错误出现的原因这是因为子类无法访问超类的私有成员。

静态和动态多态性之间的差异

静态多态性 动态多态性
它涉及方法重载。 它涉及方法覆盖。
错误(如果有)在编译时解决。由于代码在编译期间未执行,因此名称为 static。 如果引用变量正在调用重写方法,则要调用的方法由对象确定,你的引用变量指向该方法。这只能在运行时确定正在执行的代码时,因此名称为 dynamic。

举例

  • 静态多态性:

    void sum (int a , int b);
    void sum (float a, double b);
    int sum (int a, int b); //compiler gives error.
    
  • 动态多态性:

    //reference of parent pointing to child object
    Doctor obj = new Surgeon();
    // method of child called
    obj.treatPatient();