我写了这段代码
class Flower{
String name = "Flower";
void print(){System.out.println("Flower method");}
}
class Rose extends Flower{
String name = "Rose";
void print(){System.out.println("Rose method");}
}
....
//Another class in same default package
public static void main(String... args){
Flower f = new Rose();
f.print();
System.out.println(f.name);
}
我正在考虑此代码的输出为:
Flower method
Flower
但是打印
Rose method
Flower
我的经验法则是,当您使用其中一种“较小”类型作为参考时,只有它们的成员在对象中可见。您将需要强制转换才能访问其余部分。但似乎方法的处理方式不同?
答案 0 :(得分:3)
Ahaaa ..多态性。 OOP的一个更好的功能。分步说明:
Rose
是派生类,Flower
是基类 Over-ridden
。你得到了输出,因为:
f.print()
会调用 Rose 的方法,而不是 Flower 。如果您需要拨打print()
花,可以相应地使用super.print()
。f.name
正在打印Flower
,因为f
的类型为Flower
而非Rose
。您可以使用方法来访问它,如:
public String getName() { return this.name; }
并相应地使用它:System.out.println(f.getName);
编辑:要以外行的方式理解,@Juned Ahsan的回答非常简单明了:
Flower f = new Rose();
由于f
是新的Rose
,语句f.print()
将调用Rose
的方法。
认为值得一提。 :)
尝试阅读多态性。有很多参考文献。 :)
答案 1 :(得分:2)
字段不像方法那样是多态的
这里混淆了相同的字段名称。
Java language specification#shadowing.
Docs说
在类中,与超类中的字段具有相同名称的字段会隐藏超类的字段,即使它们的类型不同。在子类中,超类中的字段不能通过其简单名称引用。相反,必须通过super
访问该字段
因此,在您的情况下,超级calss name
Rose
类字段Flower
答案 2 :(得分:1)
Flower f = new Rose();
由于f
持有Rose
的对象,因此在调用时会调用Rose
的覆盖方法:
f.print();
并打印Rose method
f
是一个花卉参考,覆盖是仅methods
的概念而不是实例字段的概念,因此
System.out.println(f.name);
将打印Flower
答案 3 :(得分:0)
你正在重写Rose课程中类Flower的打印方法。这就是你得到这个输出的原因。
答案 4 :(得分:0)
当您使用“动态多态”时,超类引用保存子类对象。在你的情况下,Rose对象是f。
Flower f = new Rose();
f.print();
当你调用print方法时,它实际上在Rose类中调用了print方法。