1

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

  • 除非有向上转换,否则仅通过覆盖我们无法实现多态性。由于它只能在运行时看到,人们可能将其命名为运行时多态。(我不反对将多态称为运行时多态
  • 我反对方法重载称为编译时多态性多态性

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

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

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

据我说:

如果将多态性归入运行时多态性类别,则在更改 JDK 版本时只能看到“编译时多态性”:

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

让我阐述一下我的观点,我对运行时多态性和编译时多态性如何出现在博客/教程中的预测:

对话1

开发人员 1:嘿,我今天读到了多态性。如果对接口进行编码,则可以实现多态性。编写代码不是与类紧密耦合,而是通过松散耦合将其写入接口,调用超类方法或接口方法实际上调用子类的方法,具体取决于传递的实例。

开发人员 2:对不起,我没听懂你。

开发人员 1:在运行时很简单,您将传递哪个对象实例,然后执行该实例方法。

开发人员 2:哦!运行时间。我知道了。

开发人员 1:是的,同一段代码,但在运行时传递的实例不同。

开发人员 2:**运行时间!好的,我明白了。

对话2

开发人员 2:嘿,昨天我遇到了开发人员 1,他正在讲述一些运行时多态性。通过覆盖子类中的方法,我们可以实现它。

开发人员 3:通过重写方法实现运行时多态性?那么什么是超载呢?编译时多态?

开发人员 2:您如何将重载称为编译时多态性?

开发人员 3:因为它只在编译时决定。

开发人员 2:安静!

接口的多态性编码最好的例子是 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 实例的方法。即它执行被覆盖的方法。如果您注册了 Oracle 驱动程序,它适用于 Oracle,依此类推。

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

现在任何人都可以向我展示在编译时表现不同的相同代码。或者换句话说add(3,4),在编译期间向我展示绑定到不同方法(其他签名方法)的方法?

根据 javadoc

Java 编程语言支持重载方法,Java 可以区分具有不同方法签名的方法。

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

问题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,因为这个线程没有找到支持方法重载作为一种多态性的答案(即使在提出一个月的问题之后),没有任何理由接受支持方法重载的答案不是多态性,如果有任何答案点问题在我关于方法重载不是多态的论点中将被接受并支持他们的观点。

4

2 回答 2

1

在 Java 世界中,多态是指类之间的多态。即可能与它们的共同父类一起引用多个子类。在 Java 中,方法之间没有多态性。

void add(int a, int b)并且void add(int a, int b, int c)是 Java 语法中完全不同的方法。不应该如此——例如,在 C++ 中,您可以它们相互转换——但在 Java 中却是如此。

这里要理解的关键概念是方法签名。方法签名在一种语言中定义了标识单个方法的内容。(例如,除了 a void add(int a, int b);,您根本无法声明int add(int a, int b);方法 - 返回值不是 Java 中方法签名的一部分,因此编译器会将其解释为方法重新定义。)

于 2019-09-01T13:09:44.040 回答
1

人们说

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

两者都是错误的。
只有覆盖不是多态性。但是覆盖有助于实现多态性。如果没有向上转型,就无法实现多态性。

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

于 2019-10-04T19:59:14.307 回答