Java中的动态多态和静态多态有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20783266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between dynamic and static polymorphism in Java?
提问by Prabhakar Manthena
Can anyone provide a simple example that explains the difference between Dynamicand Staticpolymorphism in Java?
谁能提供一个简单的例子来解释Java 中动态和静态多态之间的区别?
采纳答案by KhAn SaAb
Polymorphism
多态性
1. Static binding/Compile-Time binding/Early binding/Method overloading.(in same class)
1.静态绑定/编译时绑定/早期绑定/方法重载。(在同一个类中)
2. Dynamic binding/Run-Time binding/Late binding/Method overriding.(in different classes)
2. 动态绑定/运行时绑定/后期绑定/方法覆盖。(在不同的类中)
overloading example:
重载示例:
class Calculation {
void sum(int a,int b){System.out.println(a+b);}
void sum(int a,int b,int c){System.out.println(a+b+c);}
public static void main(String args[]) {
Calculation obj=new Calculation();
obj.sum(10,10,10); // 30
obj.sum(20,20); //40
}
}
overriding example:
覆盖示例:
class Animal {
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move();//output: Animals can move
b.move();//output:Dogs can walk and run
}
}
回答by user1374
Method overloading would be an example of static polymorphism
whereas overriding would be an example of dynamic polymorphism.
Because, in case of overloading, at compile time the compiler knows which method to link to the call. However, it is determined at runtime for dynamic polymorphism
方法重载将是静态多态的一个例子
而覆盖将是动态多态性的一个例子。
因为,在重载的情况下,编译器在编译时知道将哪个方法链接到调用。但是,它是在运行时确定的动态多态性
回答by rachana
Dynamic (run time) polymorphismis the polymorphism existed at run-time. Here, Java compiler does not understand which method is called at compilation time. Only JVM decides which method is called at run-time. Method overloading and method overriding using instance methods are the examples for dynamic polymorphism.
动态(运行时)多态是运行时存在的多态性。在这里,Java 编译器不知道在编译时调用了哪个方法。只有 JVM 决定在运行时调用哪个方法。方法重载和使用实例方法的方法覆盖是动态多态的例子。
For example,
例如,
Consider an application that serializes and de-serializes different types of documents.
We can have ‘Document' as the base class and different document type classes deriving from it. E.g. XMLDocument , WordDocument , etc.
Document class will define ‘ Serialize() ' and ‘ De-serialize() ' methods as virtual and each derived class will implement these methods in its own way based on the actual contents of the documents.
When different types of documents need to be serialized/de-serialized, the document objects will be referred by the ‘ Document' class reference (or pointer) and when the ‘ Serialize() ' or ‘ De-serialize() ' method are called on it, appropriate versions of the virtual methods are called.
考虑一个序列化和反序列化不同类型文档的应用程序。
我们可以将“文档”作为基类,并从它派生出不同的文档类型类。例如 XMLDocument 、 WordDocument 等。
文档类将“ Serialize() ”和“ De-serialize() ”方法定义为虚拟方法,每个派生类将根据文档的实际内容以自己的方式实现这些方法。
当需要对不同类型的文档进行序列化/反序列化时,文档对象将通过 'Document' 类引用(或指针)引用,并且当调用 'Serialize()' 或 'De-serialize()' 方法时在它上面,调用适当版本的虚拟方法。
Static (compile time) polymorphismis the polymorphism exhibited at compile time. Here, Java compiler knows which method is called. Method overloading and method overriding using static methods; method overriding using private or final methods are examples for static polymorphism
静态(编译时)多态性是在编译时表现出的多态性。在这里,Java 编译器知道调用了哪个方法。使用静态方法的方法重载和方法覆盖;使用私有或最终方法覆盖的方法是静态多态的例子
For example,
例如,
An employee object may have two print() methods one taking no arguments and one taking a prefix string to be displayed along with the employee data.
Given these interfaces, when the print() method is called without any arguments, the compiler, looking at the function arguments knows which function is meant to be called and it generates the object code accordingly.
一个员工对象可能有两种 print() 方法,一种不带参数,另一种带有前缀字符串,与员工数据一起显示。
给定这些接口,当 print() 方法在没有任何参数的情况下被调用时,编译器查看函数参数就知道要调用哪个函数并相应地生成目标代码。
For more details please read "What is Polymorphism" (Google it).
有关更多详细信息,请阅读“什么是多态性”(Google it)。
回答by Sujith PS
method overloadingis an example of compile time/static polymorphism because method binding between method call and method definition happens at compile time and it depends on the reference of the class (reference created at compile time and goes to stack).
方法重载是编译时/静态多态的一个例子,因为方法调用和方法定义之间的方法绑定发生在编译时,它取决于类的引用(在编译时创建的引用并进入堆栈)。
method overridingis an example of run time/dynamic polymorphism because method binding between method call and method definition happens at run time and it depends on the object of the class (object created at runtime and goes to the heap).
方法覆盖是运行时/动态多态的一个例子,因为方法调用和方法定义之间的方法绑定发生在运行时,它取决于类的对象(在运行时创建的对象并进入堆)。
回答by loknath
Polymorphism:Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.
多态性:多态性是对象具有多种形式的能力。当使用父类引用来引用子类对象时,OOP 中多态性的最常见用途发生。
Dynamic Binding/Runtime Polymorphism :
动态绑定/运行时多态:
Run time Polymorphism also known as method overriding. In this Mechanism by which a call to an overridden function is resolved at a Run-Time.
运行时多态也称为方法覆盖。在此机制中,在运行时解析对重写函数的调用。
public class DynamicBindingTest {
public static void main(String args[]) {
Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
vehicle.start(); //Car's start called because start() is overridden method
}
}
class Vehicle {
public void start() {
System.out.println("Inside start method of Vehicle");
}
}
class Car extends Vehicle {
@Override
public void start() {
System.out.println("Inside start method of Car");
}
}
Output:
输出:
Inside start method of Car
汽车内部启动方法
Static Binding /compile-time polymorphism:
静态绑定/编译时多态:
Which method is to be called is decided at compile-time only.
调用哪个方法仅在编译时决定。
public class StaticBindingTest {
public static void main(String args[]) {
Collection c = new HashSet();
StaticBindingTest et = new StaticBindingTest();
et.sort(c);
}
//overloaded method takes Collection argument
public Collection sort(Collection c){
System.out.println("Inside Collection sort method");
return c;
}
//another overloaded method which takes HashSet argument which is sub class
public Collection sort(HashSet hs){
System.out.println("Inside HashSet sort method");
return hs;
}
}
Output: Inside Collection sort metho
输出:内部集合排序方法
回答by Ravindra babu
In simple terms :
简单来说 :
Static polymorphism: Same method name is overloadedwith different type or number of parameters in same class(different signature). Targeted method call is resolved at compile time.
静态多态性:相同的方法名称在相同的类(不同的签名)中使用不同类型或数量的参数进行重载。目标方法调用在编译时解决。
Dynamic polymorphism: Same method is overriddenwith same signature in different classes. Type of object on which method is being invoked is not known at compile time but will be decided at run time.
动态多态:在不同的类中用相同的签名覆盖相同的方法。被调用方法的对象类型在编译时是未知的,但将在运行时决定。
Generally overloading won't be considered as polymorphism.
通常重载不会被视为多态。
From java tutorial page:
从java教程页面:
Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class
一个类的子类可以定义它们自己独特的行为,同时共享父类的一些相同功能
回答by Naresh Joshi
Method Overloadingis known as Static Polymorphismand also Known as Compile Time Polymorphismor Static Bindingbecause overloaded method calls get resolved at compile time by the compiler on the basis of the argument list and the reference on which we are calling the method.
方法重载被称为静态多态,也称为编译时多态或静态绑定,因为重载的方法调用在编译时由编译器根据参数列表和我们调用方法的引用来解决。
And Method Overridingis known as Dynamic Polymorphismor simple Polymorphismor Runtime Method Dispatchor Dynamic Bindingbecause overridden method call get resolved at runtime.
和方法覆盖被称为动态多态性或简单的多态性和运行方法分派或动态绑定,因为重写的方法调用在运行时得到解决。
In order to understand why this is so let's take an example of Mammal
and Human
class
为了理解为什么会这样,让我们举一个例子Mammal
和Human
类
class Mammal {
public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}
class Human extends Mammal {
@Override
public void speak() { System.out.println("Hello"); }
public void speak(String language) {
if (language.equals("Hindi")) System.out.println("Namaste");
else System.out.println("Hello");
}
}
I have included output as well as bytecode of in below lines of code
我在下面的代码行中包含了输出和字节码
Mammal anyMammal = new Mammal();
anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V
human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
And by looking at above code we can see that the bytecodes of humanMammal.speak() , human.speak() and human.speak("Hindi") are totally different because the compiler is able to differentiate between them based on the argument list and class reference. And this is why Method Overloadingis known as Static Polymorphism.
通过查看上面的代码,我们可以看到 humanMammal.speak() 、 human.speak() 和 human.speak("Hindi") 的字节码完全不同,因为编译器能够根据参数列表区分它们和类参考。这就是方法重载被称为静态多态的原因。
But bytecode for anyMammal.speak() and humanMammal.speak() is same because according to compiler both methods are called on Mammal reference but the output for both method calls is different because at runtime JVM knows what object a reference is holding and JVM calls the method on the object and this is why Method Overriding is known as Dynamic Polymorphism.
但是 anyMammal.speak() 和 humanMammal.speak() 的字节码是相同的,因为根据编译器,这两种方法都是在 Mammal 引用上调用的,但是两种方法调用的输出是不同的,因为在运行时 JVM 知道引用所持有的对象和 JVM 调用对象上的方法,这就是方法覆盖被称为动态多态的原因。
So from above code and bytecode, it is clear that during compilation phase calling method is considered from the reference type. But at execution time method will be called from the object which the reference is holding.
所以从上面的代码和字节码可以看出,在编译阶段调用方法是从引用类型考虑的。但是在执行时方法将从引用持有的对象中调用。
If you want to know more about this you can read more on How Does JVM Handle Method Overloading and Overriding Internally.
如果您想了解更多相关信息,您可以阅读更多关于JVM 如何在内部处理方法重载和覆盖。
回答by Manoj Gururaj
Method overloading is a compile time polymorphism, let's take an example to understand the concept.
方法重载是一种编译时多态,我们举个例子来理解这个概念。
class Person //person.java file
{
public static void main ( String[] args )
{
Eat e = new Eat();
e.eat(noodle); //line 6
}
void eat (Noodles n) //Noodles is a object line 8
{
}
void eat ( Pizza p) //Pizza is a object
{
}
}
In this example, Person has a eat method which represents that he can either eat Pizza or Noodles. That the method eat is overloaded when we compile this Person.java the compiler resolves the method call " e.eat(noodles) [which is at line 6] with the method definition specified in line 8 that is it method which takes noodles as parameter and the entire process is done by Compiler so it is Compile time Polymorphism. The process of replacement of the method call with method definition is called as binding, in this case, it is done by the compiler so it is called as early binding.
在这个例子中,Person 有一个 eat 方法,表示他可以吃 Pizza 或 Noodles。当我们编译这个 Person.java 时,eat 方法被重载,编译器解析方法调用“e.eat(noodles) [在第 6 行],其方法定义在第 8 行中指定,即 it 方法将面条作为参数而整个过程是由Compiler完成的,所以是Compile time Polymorphism,将方法调用替换为方法定义的过程称为绑定,在这种情况下,是由编译器完成的,所以称为早期绑定。
回答by Elsayed
Binding refers to the link between method call and method definition.
绑定是指方法调用和方法定义之间的链接。
This picture clearly shows what is binding.
这张图片清楚地显示了什么是绑定。
In this picture, “a1.methodOne()” call is binding to corresponding methodOne() definition and “a1.methodTwo()” call is binding to corresponding methodTwo() definition.
在这张图中,“a1.methodOne()”调用绑定了对应的methodOne()定义,“a1.methodTwo()”调用绑定了对应的methodTwo()定义。
For every method call there should be proper method definition. This is a rule in java. If compiler does not see the proper method definition for every method call, it throws error.
对于每个方法调用,都应该有正确的方法定义。这是java中的规则。如果编译器没有看到每个方法调用的正确方法定义,它就会抛出错误。
Now, come to static binding and dynamic binding in java.
现在,来谈谈java中的静态绑定和动态绑定。
Static Binding In Java :
Java中的静态绑定:
Static binding is a binding which happens during compilation. It is also called early binding because binding happens before a program actually runs
静态绑定是在编译期间发生的绑定。它也称为早期绑定,因为绑定发生在程序实际运行之前
.
.
Static binding can be demonstrated like in the below picture.
静态绑定可以如下图所示进行演示。
In this picture, ‘a1' is a reference variable of type Class A pointing to object of class A. ‘a2' is also reference variable of type class A but pointing to object of Class B.
在这张图中,'a1'是A类引用变量,指向A类对象。'a2'也是A类引用变量,但指向B类对象。
During compilation, while binding, compiler does not check the type of object to which a particular reference variable is pointing. It just checks the type of reference variable through which a method is called and checks whether there exist a method definition for it in that type.
在编译期间,在绑定时,编译器不会检查特定引用变量指向的对象类型。它只是检查调用方法的引用变量的类型,并检查该类型中是否存在针对它的方法定义。
For example, for “a1.method()” method call in the above picture, compiler checks whether there exist method definition for method() in Class A. Because ‘a1′ is Class A type. Similarly, for “a2.method()” method call, it checks whether there exist method definition for method() in Class A. Because ‘a2′ is also Class A type. It does not check to which object, ‘a1' and ‘a2' are pointing. This type of binding is called static binding.
例如,对于上图中的“a1.method()”方法调用,编译器检查A类中是否存在method()的方法定义。因为'a1'是A类类型。同样,对于“a2.method()”方法调用,它会检查A类中是否存在method()的方法定义。因为'a2'也是A类类型。它不检查“a1”和“a2”指向哪个对象。这种类型的绑定称为静态绑定。
Dynamic Binding In Java :
Java 中的动态绑定:
Dynamic binding is a binding which happens during run time. It is also called late binding because binding happens when program actually is running.
动态绑定是在运行时发生的绑定。它也称为后期绑定,因为绑定发生在程序实际运行时。
During run time actual objects are used for binding. For example, for “a1.method()” call in the above picture, method() of actual object to which ‘a1' is pointing will be called. For “a2.method()” call, method() of actual object to which ‘a2' is pointing will be called. This type of binding is called dynamic binding.
在运行时实际对象用于绑定。例如,对于上图中的“a1.method()”调用,将调用“a1”所指向的实际对象的method()。对于“a2.method()”调用,将调用“a2”指向的实际对象的method()。这种类型的绑定称为动态绑定。
The dynamic binding of above example can be demonstrated like below.
上面例子的动态绑定可以如下所示。
回答by Kulasangar
Static Polymorphism:is where the decision to resolve which method to accomplish, is determined during the compile time. Method Overloading could be an example of this.
静态多态性:是在编译期间确定要完成的方法的决定。方法重载就是一个例子。
Dynamic Polymorphism:is where the decision to choose which method to execute, is set during the run-time. Method Overriding could be an example of this.
动态多态:是在运行时设置选择执行哪个方法的决定。方法覆盖可能就是一个例子。