我的代码形式为SCJP:
1. class Mammal {
2. String name = "furry ";
3. String makeNoise() { return "generic noise"; }
4. }
5.
6. class Zebra extends Mammal {
7. String name = "stripes ";
8. String makeNoise() { return "bray"; }
9. }
10.
11. public class ZooKeeper {
12. public static void main(String[] args) {
13. new ZooKeeper().go();
14. }
15.
16. void go() {
17. Mammal m = new Zebra();
18. System.out.println(m.name + m.makeNoise());
19. }
20. }
运行此代码的结果是“毛茸茸的bray”。
问题1
我不明白为什么第17行不是: Zebra zebra2 =新Zebra();
以下每种情况的目的是什么,何时使用?
Mammal zebra1 = new Zebra();
VS
Zebra zebra2 = new Zebra();
问题2
为什么name = "stripes"
类中的变量Zebra
会被name = "furry"
类的Mammal
覆盖?我希望反对者:来自子类的变量将覆盖来自超类的变量。
答案 0 :(得分:6)
回答1
Mammal zebra1 = new Zebra();
用于表明您可以将派生类的对象分配给父类的类型的变量。这也是Mammal m
的原因,因为您还可以从Mammal派生一个类Lion
并将其分配给m
。 m
可以包含类Mammal
的对象或从Mammal
派生的任何类。
回答2
这也与继承有关。当您打印m.name
m
为Mammal
时,您将获得Mammal
类的该属性的值。您不能通过继承覆盖变量,只能覆盖方法。
如果您向两个类都添加方法getName()
,其中两个方法都会返回name
,m.getName()
将返回"stripes"
。
答案 1 :(得分:1)
因为Zebra
Mammal
无法覆盖变量。如果您将第15行更改为:
System.out.println(((Zebra) m).name + m.makeNoise());
您将获得stripes bray
答案 2 :(得分:1)
答案1:取决于你想要什么。在这种情况下,它并不那么明显。但有时候你只想让一个物体离开1级或2级。想象一下你在斑马中有一种方法,而不是在哺乳动物中,你想要使用那种方法,那么你的物体需要离类斑马而不是哺乳动物。但是如果有第三方课程的方法只接受哺乳动物变量,那么你必须传递一个哺乳动物。
答案2:m.name是哺乳动物的变量(不能被覆盖),m.makeNoise()是一种方法,这在Zebra中被覆盖。