📜  Java中的静态与动态绑定

📅  最后修改于: 2022-05-13 01:54:45.459000             🧑  作者: Mango

Java中的静态与动态绑定

在继续之前需要记住一些关键点,我们将在后面讨论和实现Java中的静态和动态绑定,从而得出差异。

  • 私有、最终和静态成员(方法和变量)使用静态绑定,而对于虚拟方法(在Java中方法默认为虚拟),绑定是在运行时基于运行时对象完成的。
  • 静态绑定使用类型信息进行绑定,而动态绑定使用对象解析绑定。
  • 重载的方法使用静态绑定来解决(决定当有多个同名的方法时调用哪个方法),而重载的方法使用动态绑定,即在运行时。

静态绑定

编译器可以在编译时解析的绑定称为静态绑定或早期绑定。所有静态、私有和最终方法的绑定都是在编译时完成的。

例子:

Java
// Java Program to Illustrate Static Binding
 
// Main class
class NewClass {
 
    // Static nested inner class
    // Class 1
    public static class superclass {
 
        // Method of inner class
        static void print()
        {
 
            // Print statement
            System.out.println(
                "print() in superclass is called");
        }
    }
 
    // Static nested inner class
    // Class 2
    public static class subclass extends superclass {
 
        // Method of inner class
        static void print()
        {
 
            // print statement
            System.out.println(
                "print() in subclass is called");
        }
    }
 
    // Method of main class
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating objects of static inner classes
        // inside main() method
        superclass A = new superclass();
        superclass B = new subclass();
 
        // Calling method over above objects
        A.print();
        B.print();
    }
}


Java
// Java Program to Illustrate Dynamic Binding
 
// Main class
public class GFG {
 
    // Static nested inner class
    // Class 1
    public static class superclass {
 
        // Method of inner class 1
        void print()
        {
 
            // Print statement
            System.out.println(
                "print in superclass is called");
        }
    }
 
    // Static nested inner class
    // Class 2
    public static class subclass extends superclass {
 
        // Method of inner class 2
        @Override void print()
        {
 
            // Print statement
            System.out.println(
                "print in subclass is called");
        }
    }
 
    // Method inside main class
    public static void main(String[] args)
    {
 
        // Creating object of inner class 1
        // with reference to constructor of super class
        superclass A = new superclass();
 
        // Creating object of inner class 1
        // with reference to constructor of sub class
        superclass B = new subclass();
 
        // Calling print() method over above objects
        A.print();
        B.print();
    }
}


输出
print() in superclass is called
print() in superclass is called

输出说明:如您所见,在这两种情况下都调用了超类的 print 方法。让我们讨论一下这是如何发生的

  • 我们使用超类的引用创建了一个子类对象和一个超类对象。
  • 由于超类的 print 方法是静态的,编译器知道它不会在子类中被覆盖,因此编译器在编译期间知道要调用哪个 print 方法,因此没有歧义。

作为练习,读者可以将对象 B 的引用更改为子类,然后检查输出。

动态绑定

在动态绑定编译器不决定要调用的方法。覆盖是动态绑定的完美示例。在覆盖父类和子类时具有相同的方法。

例子:

Java

// Java Program to Illustrate Dynamic Binding
 
// Main class
public class GFG {
 
    // Static nested inner class
    // Class 1
    public static class superclass {
 
        // Method of inner class 1
        void print()
        {
 
            // Print statement
            System.out.println(
                "print in superclass is called");
        }
    }
 
    // Static nested inner class
    // Class 2
    public static class subclass extends superclass {
 
        // Method of inner class 2
        @Override void print()
        {
 
            // Print statement
            System.out.println(
                "print in subclass is called");
        }
    }
 
    // Method inside main class
    public static void main(String[] args)
    {
 
        // Creating object of inner class 1
        // with reference to constructor of super class
        superclass A = new superclass();
 
        // Creating object of inner class 1
        // with reference to constructor of sub class
        superclass B = new subclass();
 
        // Calling print() method over above objects
        A.print();
        B.print();
    }
}
输出
print in superclass is called
print in subclass is called

输出说明:这里的输出不同。但为什么?让我们分解代码并彻底理解它。

  • 此代码中的方法不是静态的。
  • 在编译期间,编译器不知道必须调用哪个 print,因为编译器仅通过引用变量而不是对象类型进行,因此绑定将延迟到运行时,因此相应版本的 print 将是根据对象的类型调用。

现在让我们最终看看静态绑定和动态绑定之间的区别如下:

Static BindingDynamic Binding
It takes place at compile time for which is referred to as early bindingIt takes place at runtime so do it is referred to as late binding.  
It uses overloading more precisely operator overloading methodIt uses overriding methods.
It takes place using normal functions It takes place using virtual functions  
Real objects never use static bindingReal objects use dynamic binding.