【问题标题】:Example of Runtime polymorphism in Java?Java中的运行时多态性示例?
【发布时间】:2015-05-11 18:53:09
【问题描述】:

运行时多态与静态多态有何不同?

这可以是运行时多态的一个例子吗?

public class X
{
    public void methodA() // Base class method
    {
        System.out.println ("hello, I'm methodA of class X");
    }
}

public class Y extends X
{
    public void methodA() // Derived Class method
    {
        System.out.println ("hello, I'm methodA of class Y");
    }
}
public class Z
{
   public static void main (String args []) {
       X obj1 = new X(); // Reference and object X
       X obj2 = new Y(); // X reference but Y object
       obj1.methodA();
       obj2.methodA();
   }
}

代码选自here

【问题讨论】:

  • 是的,这是运行时多态性的一个例子......和Difference is here
  • 您可以在following answer 中看到另一个完整的 Java 示例。
  • Y obj1 = new X();这是不正确的,在运行时多态的情况下,您不能将父级转换为子级。

标签: java polymorphism


【解决方案1】:

是的,您的示例是运行时多态性的示例。静态多态性的一个例子是方法重载。这里有一些很好的例子: What is the difference between dynamic and static polymorphism in Java?

干杯,

马库斯

【讨论】:

    【解决方案2】:

    为了您更好地理解,我已尝试修改您的代码。注意这两个类的构造函数调用。

    class X
    {
        X(){
            System.out.println("X constructor called");
        }
        public void methodA() //Base class method
        {
            System.out.println ("hello, I'm methodA of class X");
        }
    }
    
    class Y extends X
    {
        Y(){
             System.out.println("Y constructor called");
        }
    
        public void methodA() //Derived Class method
        {
            System.out.println ("hello, I'm methodA of class Y");
        }
    }
    
    public class Z
    {
       public static void main (String args []) {
           X obj1 = new X(); // Reference and object X
           X obj2 = new Y(); // X reference but Y object
           obj1.methodA();
           obj2.methodA();
       }
    }
    

    输出:-

    调用X构造函数

    调用X构造函数

    Y 构造函数被调用

    你好,我是X类的methodA

    你好,我是Y类的methodA

    仔细查看创建对象的位置。似乎 X 的引用是使用 y 创建的。预期会调用 X 的方法,但用于创建 X 引用的 Y 的构造函数调用间接表示在创建 X 的引用之前已将内存分配给 Y 的对象。请查看控制台以进行澄清。

    【讨论】:

      【解决方案3】:

      是的,这是 Java 中的 Runtime polymorphism

      static polymorphism 中,编译器自己决定应该调用哪个方法。 Method overloading 是静态多态的一个例子。

      runtime polymorphism 中,编译器无法在编译时确定方法。 Method overriding(作为你的例子)是runtime polymorphism 的一个例子。 因为在Runtime polymorphism(作为您的示例)中,methodA() 的签名在X(base class)Y(child class) 类中都是相似的。因此编译器无法在编译时确定应该执行的方法。 只有在对象创建之后(这是一个运行时过程),运行时环境才知道要调用的确切方法。

      因为在这种情况下,obj1.methodA()Class X 中调用methodA(),因为obj1 是为class X 创建的对象的引用变量

      obj2.methodA()Class Y 中调用methodA(),因为obj2 是为class Y 创建的对象的引用变量

      【讨论】:

      • 很好的解释
      【解决方案4】:

      它的运行时多态性,因为编译器直到运行时才知道要调用哪个对象方法。

      但是下面这行会给你转换异常:

      Y obj1 = 新 X(); //不正确的方式

      X obj1 = 新 Y(); //正确的方式

      现在 obj1.methodA() 在 Y 类中调用 methodA(),因为 obj1 是为 Y 类创建的对象的引用变量

      【讨论】:

        【解决方案5】:

        我稍微改变了main方法如下:

        public class X
        {
            public void methodA() // Base class method
            {
                System.out.println ("hello, I'm methodA of class X");
            }
        }
        
        public class Y extends X
        {
            public void methodA() // Derived Class method
            {
                System.out.println ("hello, I'm methodA of class Y");
            }
        }
        public class Z
        {
        public static void main (String args []) {
        
            //this takes input from the user during runtime
            System.out.println("Enter x or y");
            Scanner scanner = new Scanner(System.in);
            String value= scanner.nextLine();
        
            if(value.equals("x"))
                X obj1 = new X(); // Reference and object X
            else if(value.equals("y"))
                X obj2 = new Y(); // X reference but Y object
            else
                System.out.println("Invalid param value");
        
            obj1.methodA();
            obj2.methodA();
        }
        }
        

        现在,查看代码,您永远无法判断将调用哪个方法。因为它取决于用户在运行时给出的值。因此,仅在运行时决定将调用哪个方法。因此,运行时多态性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-19
          • 2011-01-10
          • 1970-01-01
          • 1970-01-01
          • 2021-11-23
          • 2013-02-22
          相关资源
          最近更新 更多