Java 中的意外多态行为如果重载和覆盖相同的方法
Unexpected Polymorphism Behaviour In Java if same method overloaded and overridden
我一直在我的项目中做一些更改,我发现一些奇怪的或者我会说 Java 中多态性的意外行为。我在下面给出的 Poc 中复制了相同的行为。
1. CommonInterface.java
package com.general;
public interface CommonInterface {
public void getViews(String str);
public void getViews(String str, Long id);
}
2。 GenericUtility.java
package com.general;
public class GenericUtility implements CommonInterface{
@Override
public void getViews(String str) {
System.out.println("This is getViews (single param)from GenericUtility");
getViews(str, null);
}
@Override
public void getViews(String str, Long id) {
System.out.println("This is getViews (multi-param) from GenericUtility");
}
}
3。 CustomUtility.java
package com.general;
public class CustomUtility extends GenericUtility {
@Override
public void getViews(String str) {
System.out.println("This is getViews (single param)from CustomUtility");
super.getViews(str);
}
@Override
public void getViews(String str, Long id) {
System.out.println("This is getViews (multi-param) from CustomUtility");
super.getViews(str, null);
}
}
4. Main.java
package com.general;
public class Main {
public static void main(String[] args) {
GenericUtility utility = new CustomUtility();
String str = "Random String";
utility.getViews(str);
}
}
在 运行 Main.java 之后,我的预期输出是
This is getViews (single param)from CustomUtility
This is getViews (single param)from GenericUtility
This is getViews (multi-param) from GenericUtility
但是我得到的输出是
This is getViews (single param)from CustomUtility
This is getViews (single param)from GenericUtility
This is getViews (multi-param) from CustomUtility
This is getViews (multi-param) from GenericUtility
我无法理解为什么 com.general.GenericUtility#getViews(java.lang.String)
调用 com.general.CustomUtility#getViews(java.lang.String, java.lang.Long)
这是预期的行为吗?我不知道这是什么?
提前致谢。
Java 使用运行时虚拟分派调用实例方法(即非静态方法)。这仍然适用于对 this
的调用;例如,抽象 class 可以定义抽象方法 createResultObject
以由子 class 实现,并在其 doProcessing
方法中使用该方法。
在你的例子中,对象 是 一个 CustomUtility
,因此对 this.getViews(String, String)
的调用被分派给 CustomUtility
,然后使用 super
内部。
当GenericUtility.getViews(String)
调用getViews(str, null);
时,将调用的getViews(String, Long)
实现是CustomUtility.getViews(String, Long)
。
那是因为 CustomUtility
也覆盖了该方法。无论从何处调用方法(包括超类),对重写方法的调用都会导致重写实现 运行。唯一可以改变这一点的是子类使用 super
.
显式调用该方法
大致情况如下:
main
调用 utility.getViews(str);
,这会导致覆盖
CustomUtility.getViews(String)
到 运行.
CustomUtility.getViews(String)
调用 super.getViews(str)
,这
导致 GenericUtility.getViews(String)
到 运行。
GenericUtility.getViews(String)
调用 getViews(str, null)
,这
导致 覆盖 CustomUtility.getViews(String, Long)
到 运行
(与您的预期相反)
CustomUtility.getViews(String, Long)
来电
super.getViews(str, null)
,调用
GenericUtility.getViews(String, Long)
到 运行.
我一直在我的项目中做一些更改,我发现一些奇怪的或者我会说 Java 中多态性的意外行为。我在下面给出的 Poc 中复制了相同的行为。
1. CommonInterface.java
package com.general;
public interface CommonInterface {
public void getViews(String str);
public void getViews(String str, Long id);
}
2。 GenericUtility.java
package com.general;
public class GenericUtility implements CommonInterface{
@Override
public void getViews(String str) {
System.out.println("This is getViews (single param)from GenericUtility");
getViews(str, null);
}
@Override
public void getViews(String str, Long id) {
System.out.println("This is getViews (multi-param) from GenericUtility");
}
}
3。 CustomUtility.java
package com.general;
public class CustomUtility extends GenericUtility {
@Override
public void getViews(String str) {
System.out.println("This is getViews (single param)from CustomUtility");
super.getViews(str);
}
@Override
public void getViews(String str, Long id) {
System.out.println("This is getViews (multi-param) from CustomUtility");
super.getViews(str, null);
}
}
4. Main.java
package com.general;
public class Main {
public static void main(String[] args) {
GenericUtility utility = new CustomUtility();
String str = "Random String";
utility.getViews(str);
}
}
在 运行 Main.java 之后,我的预期输出是
This is getViews (single param)from CustomUtility
This is getViews (single param)from GenericUtility
This is getViews (multi-param) from GenericUtility
但是我得到的输出是
This is getViews (single param)from CustomUtility
This is getViews (single param)from GenericUtility
This is getViews (multi-param) from CustomUtility
This is getViews (multi-param) from GenericUtility
我无法理解为什么 com.general.GenericUtility#getViews(java.lang.String)
调用 com.general.CustomUtility#getViews(java.lang.String, java.lang.Long)
这是预期的行为吗?我不知道这是什么?
提前致谢。
Java 使用运行时虚拟分派调用实例方法(即非静态方法)。这仍然适用于对 this
的调用;例如,抽象 class 可以定义抽象方法 createResultObject
以由子 class 实现,并在其 doProcessing
方法中使用该方法。
在你的例子中,对象 是 一个 CustomUtility
,因此对 this.getViews(String, String)
的调用被分派给 CustomUtility
,然后使用 super
内部。
当GenericUtility.getViews(String)
调用getViews(str, null);
时,将调用的getViews(String, Long)
实现是CustomUtility.getViews(String, Long)
。
那是因为 CustomUtility
也覆盖了该方法。无论从何处调用方法(包括超类),对重写方法的调用都会导致重写实现 运行。唯一可以改变这一点的是子类使用 super
.
大致情况如下:
main
调用utility.getViews(str);
,这会导致覆盖CustomUtility.getViews(String)
到 运行.CustomUtility.getViews(String)
调用super.getViews(str)
,这 导致GenericUtility.getViews(String)
到 运行。GenericUtility.getViews(String)
调用getViews(str, null)
,这 导致 覆盖CustomUtility.getViews(String, Long)
到 运行 (与您的预期相反)CustomUtility.getViews(String, Long)
来电super.getViews(str, null)
,调用GenericUtility.getViews(String, Long)
到 运行.