动态方法分派和运行时多态性错误
Posted
技术标签:
【中文标题】动态方法分派和运行时多态性错误【英文标题】:Dynamic method dispatch and runtime polymorphism error 【发布时间】:2020-04-29 03:54:04 【问题描述】:我正在尝试理解动态方法调度。
class A
int i=10;
void callme()
System.out.println("Inside A's callme method");
class B extends A
int j=20;
void callme()
System.out.println("Inside B's callme method");
class C extends A
int k=30;
void callme()
System.out.println("Inside C's callme method");
class Over_riding_loading
public static void main(String args[])
A a = new A();
B b = new B();
C c = new C();
A r;
B r; //error when i am using this instead of A r;
C r; //error when i am using this instead of Ar and B r;
r = a;
r.callme();
System.out.println(r.i);//prints 10
r = b;
r.callme();
System.out.println(r.j);//j cannot be resolved or is not a field--what does this mean?
r = c;
r.callme();
System.out.println(r.k);//k cannot be resolved or is not a field
为什么会显示错误?为什么我不能创建 B 或 C 类型的变量 r 并调用 callme() 方法?
已编辑:为了澄清一些事情,我不想使用相同的变量名,我想说的是,而不是 A r;我正在尝试使用 B r 并保持其余代码相同。
【问题讨论】:
不同类型的变量名不能相同(在同一范围内) 【参考方案1】:不同类型的变量名不能相同(在同一范围内)
修改你的主要方法为
public static void main(String args[])
A a = new A();
B b = new B();
C c = new C();
A r;
//you cannot have same variable name for different types (in same scope)
//B r; // error
//C r; // error
r = a;
r.callme();
System.out.println(r.i);// prints 10
r = b;
r.callme();
//here you're getting error because object is available at runtime, what you are getting is a compile time error
System.out.println(r.j);// can be resolved by casting it as System.out.println(((B)r).j)
r = c;
r.callme();
// here you're getting error because object is available at runtime, what you are getting is a compile time error
System.out.println(r.k);// can be resolved by casting it as System.out.println(((C)r).k);
希望对你有帮助!!
【讨论】:
【参考方案2】:在运行时,它取决于被引用对象的类型(而不是引用变量的类型),它决定了将执行覆盖方法的哪个版本。
超类引用变量可以引用子类对象。这也称为向上转换。 Java 使用这一事实来解决在运行时对覆盖方法的调用。但反之亦然。
声明 B r1
和 C r2
。您为所有三个类指向相同的变量名称。
通过r= b
,您将A 对象引用到r(因为r 已经通过r=a
引用了A)。因此,当您调用 r.j
时,它会给出错误,因为 j 是 B 对象的属性。
r.k
case 的解释也一样
【讨论】:
【参考方案3】:B r; //错误 C r; //错误
出现上述错误是因为您尝试将相同的变量名r
用于不同的类类型 A、B 和 C。由于首先使用了 A,因此在编译和任何后续尝试时都会注册它更改variable r
的类型最终会导致编译时错误。
System.out.println(r.j); System.out.println(r.k);
这些错误发生在编译时,因为在编译期间,class A
中会查找 variable j
和 variable k
。发生这种情况是因为您的 variable r
属于 A 类型。如果您想访问 variable j
和 variable k
,请将 variable r
分别转换为 class B
和 class C
。
希望这会有所帮助!
【讨论】:
但我通过给出 r=b; 将 r 指代为 B 类和 C 类;和 r=c 语句。为什么不考虑呢? 对象分配,即右侧将在运行时出现。对于编译,仅考虑左侧。由于在 LHS 中,变量是 A 类型,因此需要显式转换才能分别访问变量 j 和 k。 这能回答您的问题吗?以上是关于动态方法分派和运行时多态性错误的主要内容,如果未能解决你的问题,请参考以下文章
64.多态性实现机制—静态分派与动态分派(方法解析静态分派动态分派单分派和多分派)