详细说明:方法重载是 static/compile-time 绑定但不是多态性。将静态绑定与多态相关联是否正确?

Elaboration: Method overloading is a static/compile-time binding but not polymorphism. Is it correct to correlate static binding with polymorphism?

在我提出问题之前,让我解释一下我的理解和看法。

我同意方法重载是静态绑定(编译时绑定),但我看不到其中的多态性。

根据 javadoc,只有 polymorphism。没有编译时间或 运行 时间多态性。

根据名为 Defining Methods 的部分中的 javadoc,它解释了方法重载。但是没有关于编译时多态性的内容。

据我所知:

如果你把多态归入运行时间多态的类别,当你改变你的JDK版本时,你只能看到"compile time polymorphism":

如果您从较高 JDK 版本切换到较低版本,您将开始看到编译错误。相同的代码在编译期间表现不同,例如:lambda 表达式、菱形运算符、switch case 中的字符串、泛型等

让我阐述一下我的观点,我对 运行 时间多态性和编译时多态性如何产生的预测 blogs/tutorials:

对话 1

Developer 1: Hey I read about polymorphism today. If you do coding to interface, you can achieve polymorphism. writing codes not tightly coupling to a class but instead writing it to interface by making loose coupling, calling a superclass method or interface method actually invokes method of subclass depending on instance passed.

Developer 2: Sorry, I didn't get you.

Developer 1: It's simple at run time which object instance you will pass, that instance method will be executed.

Developer 2: Ohh! Run Time. I got it.

Developer 1: Yes same piece of code, but at Run Time passed instances are different.

Developer 2: **Run Time! Okay, I got it.

对话 2

Developer 2: Hey yesterday I've met Developer1, he was telling about some run-time polymorphism. By overriding methods in a sub-class we can achieve it.

Developer 3: Run time polymorphism by overriding methods? Then what is oveloading? Compile time polymorphism?

Developer 2: How do you say overloading as compile time polymorphism?

Developer 3: Because it is decided at compile time only.

Developer 2: Silent!

多态接口编码最好的例子是java.sql:

java.sql.Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
java.sql.Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery(sql);

同一段代码根据注册的驱动程序表现不同。这意味着,如果我们注册 Mysql 驱动程序,由于多态性,此代码将执行 mysql 实例的方法。 IE。它执行重写的方法。如果您注册了 Oracle 驱动程序,它适用于 Oracle,依此类推。

上面我们发现相同的代码表现不同。

现在谁能告诉我相同的代码在编译时表现不同。或者换句话说,告诉我 add(3,4) 方法在编译期间绑定到不同的方法(其他签名方法)?

According to javadoc,

The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures.

该方法将根据匹配的签名执行。方法具有相同的名称并不意味着存在多态性,因为调用方法签名不同:

问题 1:如果您不更改调用方法签名,它会调用与签名匹配的方法不同的方法吗?在任何情况下它的行为都会有所不同吗?

让我们看看方法重载:

public void add(int a, int b)
{
    System.out.println(a+b);
}

public void add(int a, int b, int c)
{
    System.out.println(a+b+c);
}

public static void main(String[] args)
{
    add(3,4);
    add(3,4,5);
}

问题1:如果方法重载是多态性,那么上面代码块中哪段代码的行为不同?多态性在哪里?

问题2:方法调用add(3,4);在什么场景下显示多态,除非修改为add(3,4,5)?


编辑
@FutureVisitor 因为这个线程没有找到支持方法重载作为一种多态性的答案(即使在问了一个月的问题之后),也没有任何理由接受支持 [=74 的答案=]方法重载不是多态,如果我的方法重载不是多态论证中的任何答案点问题将被接受并支持他们的观点

在Java的世界里,多态是指类之间的多态。 IE。可能引用多个 child 类 和他们共同的 parent。在Java中,方法之间没有多态性。

void add(int a, int b)void add(int a, int b, int c) 是 Java 语法中完全不同的方法。不应该如此 - 例如,在 C++ 中,你可以 cast 它们相互 - 但在 Java.

中是这样

这里要理解的关键概念是method signature。方法签名以一种语言定义,什么标识了各个方法。 (例如,除了 void add(int a, int b);,您根本无法声明 int add(int a, int b); 方法 - return 值不是 Java 中方法签名的一部分,因此编译器会将其解释为方法 re-definition.)

人们说

  1. 重写的是 运行 时间多态性和
  2. 重载是编译时多态性。

都错了
只有Overriding不是多态。但是覆盖有助于实现多态性。没有向上转型就无法实现多态

重载是一个概念,其中方法名称和参数签名用于将方法调用绑定到方法体,并且只能在编译时预测。但这与多态性无关。在方法重载的情况下,可以发现 NO 行为变化。要么你今天编译,要么在一年后编译行为变化只能在你改变调用方法签名时才能发现,即只有当你修改代码说 add(3,4);add(3,4,5); 并因此 方法重载时不是多态.