【发布时间】:2020-02-29 12:30:00
【问题描述】:
我有一个关于 java 中的多态性的简短问题:这里有两个类层次结构,练习是告诉代码将打印出什么。
class All { /* ... */ }
class Most extends All { /* ... */ }
class Special extends Most { /* ... */ }
class Top {
public void m( All p ) { System.out.print("A "); }
}
class Middle extends Top {
public void m( All p ) { System.out.print("M "); }
public void m( Special p ) { System.out.print("L "); }
}
class Bottom extends Middle {
public void m( Most p ) { System.out.print("V "); }
public void m( Special p ) { System.out.print("X "); }
}
class Test {
public static void main(String[] args) {
All all = new All();
Most most = new Most();
Special special = new Special();
Top x = new Middle();
Top y = new Bottom();
Middle z = new Bottom();
x.m( most );
x.m( special );
y.m( all );
y.m( special );
z.m( all );
z.m( most );
}
}
我将代码粘贴到一个 Eclipse .java 文件中,它打印出 6x M,因此每个方法的 M。谁能帮我理解一下?
显然,调用引用的参数的声明类型和参数无关紧要(根据脚本),但在这种情况下,为什么x.m(special) 不打印出“L”,因为 Special 是参数类型方法呢?
PS:我关于stackoverflow的第一个问题,真的希望有人能帮助我理解:)
【问题讨论】:
-
如果您的问题与您的代码相匹配,这将很有帮助。我没有看到“x”的定义,也没有看到“all”和“most”的用法。你能澄清一下吗?
-
当对子类对象的引用分配给超类引用变量时,您将只能访问由超类定义的对象的那些部分。在这种情况下,
x.m(special)打印“M”,因为 x 是(Top 类的)超类引用变量,它不知道 Special 类中存在哪些成员。但是如果你创建一个Middle m = new Middle;的对象,然后调用m.m(special),你会得到L。 -
"为什么
x.m(special)不打印出"L"?"x被定义为Top x = ...,这意味着x可以从Top类型中可用的方法signatures 中选择only,它只给我们public void m( All p )i>签名。当 JVM 需要找到具有已选择签名的方法的 body 时,多态就会启动,因此这里它将查看x持有的对象的实际类型,即x = new Middle();和Middle类它将搜索public void m( All p )方法的实现。
标签: java polymorphism hierarchy