java - 如何知道它是编译时多态还是运行时多态?
问题描述
考虑一个超类:
class superclass
{
public void fun() {.....}
}
它是子类:
class subclass extends superclass
{
public void fun(){.......}
public static void main()
{
superclass sup1=new superclass();
sup1.fun()//statement 1
superclass sup2=new subclass();
sup2.fun() //statement 2
subclass sub1=new subclass();
sub1.fun()//statement 3
}
}
我按照以下方式确定语句 1,2 和 3 是编译时多态还是运行时多态:
编译器首先确定调用语句中使用的引用变量的类类型,然后编译器检查源代码中是否存在此基的派生类以及调用语句中使用的方法是否在派生类中被覆盖. 如果找到派生类并且它包含函数的重写版本,则在运行时确定引用变量所引用的对象的类型,并执行该类的类型函数(运行时多态性),否则类中存在函数(引用变量所属的)被执行(编译时多态性)。
通过这种方式: 1) 语句 1 将导致运行时多态性。
2)语句2也会导致运行时多态性。
3)语句3会导致编译时多态。
问题1:我想知道这种做法是对还是错?
问题 2:当使用返回对象地址的函数调用语句代替引用变量时,过程会是什么?我认为返回地址的函数的返回类型将用于确定多态的类型。我对么?
解决方案
在 Java 中,任何可覆盖的方法总是具有运行时多态性!编译器不能知道一个类的所有可能的派生,所以它不能遵循你上面的算法。
AFAIK,逻辑是这样的:
- 在编译时,编译器使用变量的类型确定正确的签名。
- 在运行时,jvm 使用实际对象的类型和编译时确定的签名来确定正确的方法。
推荐阅读
- elasticsearch - 根据 Elasticsearch 中的嵌套字段值按表达式排序
- python - 寻找最接近多维数据点的点?
- python - Django - /uploaddd 上的 TypeError 不可散列类型:'dict'
- java - Jenkins groovy 管道:指定 Java 选项
- vue.js - 为什么组件显示两次?
- mysql - SQL 中的条件分组
- python-3.x - 创建一个给定边界框的蒙版
- c# - How to us CIL opcode bne.un vs beq, and bne.un.s vs beq.s, unsigned vs signed equality
- ms-access - Microsoft Access:使用未显示的字段过滤结果不会执行 False Null 评估
- flutter - 即使在使用 setState() 后返回屏幕时 ListView 不重建?