0

我写了这段代码

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

我的经验法则是,当您使用这些“次要”类型之一作为参考时,只有它们的成员在对象中可见。您将需要强制转换才能访问其余部分。但似乎方法的处理方式不同?

4

5 回答 5

3

啊哈..多态性。OOP 的更好特性之一。分步说明:

  1. 您正在使用单继承,其中类Rose派生类Flower基类
  2. 如果你有,在你的超类和派生类中具有相同名称的方法,默认情况下,派生类的方法被调用,而不是超类的方法。它们是Over-ridden默认的。
  3. 超类中的字段不能通过其简单名称来引用。相反,该字段必须通过 super 访问。

你得到输出是因为:

  1. f.print()将调用Rose而不是Flower的方法。如果你需要调用print()花的,你可以super.print()相应地使用。
  2. f.name正在打印Flower,因为fisFlower和 not的类型Rose。您可以使用以下方法访问它:
    公共字符串 getName()
    {
      返回这个名称;
    }

并相应地使用它:System.out.println(f.getName);

编辑:用外行的话来理解它,@Juned Ahsan 的回答非常简单明了:

Flower f = new Rose();

既然f是新Rose的,语句f.print()就会调用的方法Rose

觉得值得一提。:)

尝试阅读多态性。有大量的参考资料。:)

于 2013-10-09T09:55:53.137 回答
2

字段不是多态的方法

这里混淆了相同的字段名称。

Java 语言规范#shadowing。

文档

在一个类中,与超类中的字段同名的字段会隐藏超类的字段,即使它们的类型不同。在子类中,超类中的字段不能通过其简单名称来引用。相反,该字段必须通过 super 访问

因此,在您的情况下,超级nameRose隐藏的类字段Flower

于 2013-10-09T09:32:16.140 回答
1
Flower f = new Rose();

就像f持有对象一样,当这样调用时,将调用被Rose覆盖的方法:Rose

  f.print();

并将打印Rose method

f是花卉参考,覆盖是仅methods适用于实例字段而不适用于实例字段的概念,因此

  System.out.println(f.name);

将打印Flower

于 2013-10-09T09:31:52.437 回答
0

当您使用“动态多态性”时,您的超类引用包含子类对象。在您的情况下,Rose 对象与 f 一起使用。

Flower f = new Rose();
          f.print();

当你调用 print 方法时,它实际上调用了 Rose 类中的 print 方法。

于 2013-10-09T09:39:36.460 回答
0

您正在覆盖 Rose 类中 Flower 类的 print 方法。这就是你得到这个输出的原因。

于 2013-10-09T09:31:44.583 回答