【问题标题】:Java inheritanceJava 继承
【发布时间】:2011-03-31 04:51:49
【问题描述】:

为什么最后打印“I'm a Child Class”。 ?

public class Parent
{
    String parentString;
    public Parent()
    {
        System.out.println("Parent Constructor.");
    }

    public Parent(String myString)
    {
        parentString = myString;
        System.out.println(parentString);
    }

    public void print()
    {
       System.out.println("I'm a Parent Class.");
    }
} 

public class Child extends Parent
{
    public Child() {
        super("From Derived");
        System.out.println("Child Constructor.");
    }

    public void print()
    {
       super.print();
       System.out.println("I'm a Child Class.");
    }

    public static void main(String[] args)
    {
        Child child = new Child();
        child.print();
        ((Parent)child).print();
    }
}

输出:

From Derived

Child Constructor.

I'm a Parent Class.

I'm a Child Class.

I'm a Parent Class.

I'm a Child Class.

【问题讨论】:

    标签: java inheritance class


    【解决方案1】:

    在java中,如果我们在一个对象上调用任何方法,那么它会使用子对象调用该方法...... 这里:

    对象 | | 家长 | | Child

    案例 1::

    子子 = new Child();

        child.print();
    

    这个调用子类方法使用子对象打印...子最次 所以它打印出来

    输出::

    我是家长班。 我是儿童班。

    解释:从子方法调用父方法是因为 super.print();方法 所以第一行是我是家长班。父方法执行完成后,控件返回子方法并打印 I'm a Child Class。

    案例 2::

        ((Parent)child).print();
    if we call like this jvm calls print () method by using sub most object here sub most  object is child object so it prints 
    
    output::
              I'm a Parent Class.
              I'm a Child Class.
    

    解释:从子方法调用父方法是因为 super.print();方法 所以第一行是我是家长班。父方法执行完成后,控件返回子方法并打印 I'm a Child Class。

    【讨论】:

      【解决方案2】:

      因为这是polymorphism(后期绑定)的示例。在编译时,您指定对象的类型为Parent,因此只能调用Parent 中定义的方法。但是在运行时,当“绑定”发生时,该方法被调用到对象上,无论在代码中如何引用它都是Child类型。

      令您惊讶的部分是为什么要在运行时调用覆盖方法。在 Java 中(与 C# 和 C++ 不同),所有方法都是 virtual,因此会调用覆盖方法。请参阅this example 了解区别。

      【讨论】:

      • 好问题和好答案。这在真实程序中也是一件好事;如果您不小心有一些调用父实现的代码,您的代码可能会中断。
      【解决方案3】:

      即使您将其转换为 Parent 类,但这并不意味着它将使用其父类的函数——它只会将该对象视为 Parent。

      通过说 ((Parent)child).print();您是在说“将此对象视为父对象,而不是子对象”。不是“使用父方法实现”

      因此,如果子对象有其他方法,您将无法调用它们。但是由于 print() 是父类的方法,您仍然可以调用它,但它使用实际对象(而不是其转换为的类)的实现。

      【讨论】:

        【解决方案4】:

        即使您将 child 转换为 Parent,这也不会改变其方法的实现。这实际上并没有使它成为父母。这就是为什么您可以执行以下操作:

        Image img = new BufferedImage(...);
        

        虽然 Image 是抽象的,但 img 下面仍然是一个 bufferedImage。

        【讨论】:

          【解决方案5】:

          两者:

          child.print();
          

          ((Parent)child).print();
          

          应该返回:

          I'm a Parent Class.
          I'm a Child Class.
          

          按这个顺序。

          将对象转换为它的基类不会改变调用的方法。

          在这种情况下,即使在强制转换之后,也会调用子打印方法而不是父打印方法。

          【讨论】:

          • 让我感到困惑的是,C# 中的相同代码只打印“I'm Parent Class”
          • 继承和多态在 C# 中的工作方式完全相同。但是,c# 需要 virtual 关键字来表示您希望在继承子类时重写的方法,所以我猜您没有使用 virtual,因此您得到了不同的结果。
          猜你喜欢
          • 2012-10-30
          • 2017-12-27
          • 1970-01-01
          • 2012-02-25
          • 2015-11-16
          • 1970-01-01
          相关资源
          最近更新 更多